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

Martin Mucha mmucha at redhat.com
Wed Dec 2 10:57:41 UTC 2015


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