
thank you very much for explanation. M. ----- Original Message -----
On 12/02/2015 10:53 AM, Martin Mucha wrote:
Thanks Juan, I've read your slides and learn something new from them.
And I'd like to ask one small thing about how lambdas are represented. It seems that from early draft there were 'some changes' — from inner class representation, to runtime generated inner class representation, to no classes in the end. So if spec says, that [quote]:
The value of a lambda expression is a reference to an instance of a class with the following properties: • The class implements the targeted functional interface type and, if the target type is an intersection type, every other interface type mentioned in the intersection. …
and in current implementation class type of lambda is now it's enclosing class type, it means, that lambda is represented by instance of class its defined in(this instanceof <enclosing class> in lambda returns true). Then it seems that enclosing type has to implement functional interface to fulfill spec. Which seems wild, provided, that with two 'Runnable-representing' lambdas enclosing class has to implement Runnable twice, with two different implementations, which is usually impossible.
as you know more about this subject, can I ask you to confirm this statements / explain where I'm wrong and how it works internally / or explain what kind of sorcery is going on here?
thanks, Mar.
I'm not an expert in the subject, but as far as I understand there are two mechanisms used to implement the lambda expressions. First is that the body of the lambda expression is implemented as a method within the class were it is used. For example, if you write a class like this:
public class Test { public go() { Runnable my = () -> System.out.println("Hello!"); my.run(); } }
The compiler will ad a new synthetic method to the class, named "lambda$main$0", containing the body of the expression:
private static void labmda$main$0() { System.out.println("Hello!"); }
In this case the method is static, because the expression doesn't need to access members of the containing class, and it doesn't receive parameters because it doesn't use variables or parameters from its environment. If it used members it wouldn't have been static, and would have parameters, one for each local variable or parameter used. For example, if you change the class to this:
public class Test { String member;
public void go(String parameter) { String local = "local"; Runnable my = () -> { System.out.println(member); System.out.println(parameter); System.out.println(local); }; my.run(); } }
Then the generated method looks like this:
private void labmda$main$0(String parameter, String local) { System.out.println(member); System.out.println(parameter); System.out.println(local); }
Note that the method isn't now static, that is why it can access members, and why "this" doesn't mean the same that it means in anonymous inner classes. Note that this doesn't mean that the type of the expression is the enclosing class, just that "this" has a different meaning.
The second mechanism is the "invokedynamic" instruction, introduced in Java 7. This is used to instantiate the the object that wraps the expression. In the above example, the following line:
Runnable my = () -> { ... }
Is translated by the compiler in a "invokedynamic" instruction like this:
invokedynamic #3, 0 // InvokeDynamic #0:run:(LTest;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Runnable;
I won't go into the details here (and I don't know them very well either), but more or less this is telling the Java virtual machine that during run time, the first time that this instruction is executed, it should use the lambda expressions bootstrap method to find (maybe create, "linking" is the term) an object that implements the "Runnable" interface such that the "run" method class the "lambda$run$0" method. I guess that these classes are generated with a mechanism similar to java.lang.reflect.Proxy, but not exactly the same.
----- Original Message -----
Thanks Juan for the great presentation !!
On Wed, Dec 2, 2015 at 10:50 AM, Juan Hernández < jhernand@redhat.com > wrote:
Hello all,
The slides for the Java 8 new features that I delivered yesterday are available here:
https://jhernand.fedorapeople.org/java8/slides.html
There is no recording, as hangout failed and I forgot to record the BlueJeans call, sorry.
Regards, Juan Hernandez --
-- Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3, planta 3ºD, 28016 Madrid, Spain Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 - Red Hat S.L.