[ovirt-devel] Slides for the Java 8 presentation yesterday

Juan Hernández jhernand at redhat.com
Wed Dec 2 10:44:44 UTC 2015


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 at 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.



More information about the Devel mailing list