Skip to content

Instantly share code, notes, and snippets.

@benjiman
Created August 19, 2025 19:28
Show Gist options
  • Select an option

  • Save benjiman/4a1ae11e0320706b6ac851a36c4e30fa to your computer and use it in GitHub Desktop.

Select an option

Save benjiman/4a1ae11e0320706b6ac851a36c4e30fa to your computer and use it in GitHub Desktop.
Named parameters with lambdas
package example;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Objects;
import static example.Example.MyClass.*;
import static java.util.Arrays.asList;
public class Example {
public static void main(String... args){
// arg1=null
// arg2=Point[x=0, y=0]
foo(o -> { });
//arg1=bar
//arg2=Point[x=0, y=0]
foo(o -> o.arg1 = "bar");
//arg1=bar
//arg2=Point[x=5, y=2]
foo(o -> { o.arg1 = "bar"; o.arg3 = new Point(5,2); });
//foo
//null
bar(o -> o.arg1 = "foo");
//null
//foo
bar(o -> o.arg2 = "foo");
}
static class MyClass {
public record Point(int x, int y){}
public static class FooParams{
public String arg1 = null;
public Point arg3 = new Point(0,0);
}
public static class BarParams{
String arg1 = null;
String arg2 = null;
}
static void foo(Args<FooParams> args){
System.out.println( "arg1=" + args.args().arg1) ;
System.out.println( "arg2=" + args.args().arg3) ;
}
public static void bar(Args<BarParams> o){
System.out.println(o.args().arg1);
System.out.println(o.args().arg2);
}
}
interface Args<T> extends MethodFinder {
void accept(T args);
default T args() {
try {
T t = (T) parameter(0).getType().newInstance();
accept(t);
return t;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public interface MethodFinder extends Serializable {
default SerializedLambda serialized() {
try {
Method replaceMethod = getClass().getDeclaredMethod("writeReplace");
replaceMethod.setAccessible(true);
return (SerializedLambda) replaceMethod.invoke(this);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
default Class<?> getContainingClass() {
try {
String className = serialized().getImplClass().replaceAll("/", ".");
return Class.forName(className);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
default Method method() {
SerializedLambda lambda = serialized();
Class<?> containingClass = getContainingClass();
return asList(containingClass.getDeclaredMethods())
.stream()
.filter(method -> Objects.equals(method.getName(), lambda.getImplMethodName()))
.findFirst()
.orElseThrow(UnableToGuessMethodException::new);
}
default Parameter parameter(int n) {
return method().getParameters()[n];
}
class UnableToGuessMethodException extends RuntimeException {}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment