Java – how memory is allocated to lambda | how is it referenced through non superclass reference variables

I'm creating an implementation of the functional interface. Here's my code

Consumer<Integer> consumer=new Consumer<Integer>() {
    @Override
    public void accept(Integer t) {
        System.out.println(t);
    }
};

According to Javadoc

The object of anonymous object is created here. It is a subclass of consumer and can be referenced through the reference variable consumer. This is very fine

But I see that the consumer is a functional interface, so I can also do this in Java 8 –

Using lambda

Consumer<Integer> consumer=t->System.out.println(t);

Or use method reference

Consumer<Integer> consumer=System.out::println;

I know that subclasses or anonymous classes are not created in either case So this led me to confusion twice –

1: If the consumer here does not refer to the subclass or the anonymous class of the consumer, does this not violate the concept mentioned above? Can variables only reference child / self or null?

2: How is memory allocated to lamdas and how does the JVM handle it at runtime?

Solution

First, Jean Baptiste shows you why homework works first

Now, I think what you are missing is the consumer class generated in the case of consumer < integer > System for consumer = t – > out. println(T); Visible only at runtime due to invokedynamic

Run your class with flags:

java -Djdk.internal.lambda.dumpProxyClasses=/Your/Path

And you will notice that a generated class (in the folder path in the package name of the class) contains Class file, similar to this soquestion $$lambda $1 class.

If you decompile, you will find that it is actually a class that implements consumer:

final class org.eugene.so.soQuestion$$Lambda$1 
            implements java.util.function.Consumer {
     public void accept(java.lang.Object);
}

If you look at the generated byte code that defines a lambda, you will see that the lambda expression is actually de sugaring the static method (for a non capture lambda, if it is a capture lambda, it can also be non static)) Its code:

private static void lambda$main$0(java.lang.Integer);
Code:
   0: getstatic     #3  // Field java/lang/System.out:Ljava/io/PrintStream;
   3: aload_0
   4: invokevirtual #4  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
   7: return

As for how VM manages memory for it, for non capture lambda, you will get a single instance, and for capture lambda, you will get a new instance of each call Absolutely must read here

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>