This does not seem to be a problem for the lambda expressions themselves:
interface MyInterface { void doSomething(int a, int b); } class Test { private void bar(MyInterface iface) { iface.doSomething(0, 0); } public void foo() { bar((x, y) -> System.out.println(x)); } }
Uses a single lambda expression to make it simple. After compiling with the -parameters option -parameters we can use javap -c -p -verbose Test to find out more:
private static void lambda$foo$0(int, int); descriptor: (II)V flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC Code: stack=2, locals=2, args_size=2 0: getstatic #5
Parameter names ( x and y ) are! Iterate over such methods
for(Method m : Test.class.getDeclaredMethods()) { System.out.println(m.getName()); for(Parameter p : m.getParameters()) { System.out.println(" => " + p.getName()); } }
displays parameter names correctly:
lambda$foo$0 => x => y
Instead of being a problem with lamps, it's actually just hard to determine the right method. If you try to get the parameter names using getDeclaredMethods() on the interface instance passed to this method (like @Didier L suggested in the comment), you will have problems. For example, using
iface.getClass().getDeclaredMethods()
in bar() will not work as you might expect. If you get a class name, for example. for example iface.getClass().getName() , you will see something like this:
Test$$Lambda$1/834600351
This is a dynamically created class, you can argue about whether it exists at all. Since it is not generated by the compiler, it does not provide any information about local variables or their names, because the method implemented by the interface simply does not match your lambda . This is an important difference.
This "virtual class" provides a method, for example. doSomething(int, int) to implement this interface ( MyInterface ), but this public method is different from the method you create to define lambda ( lambda$foo$0 ).
Therefore, the doSomething method of the generated "virtual class" does not carry parameter information. A dynamically created class hides your implementation.
Your second example does not suffer from this problem:
map("bibi", new A() { @Override public JSONObject exec(String u, String s, String b) { return null; } });
You explicitly define a class that implements the A interface, and you explicitly provide the exec method, so all information is present.