問題

私は機能インターフェイスの実装を作成していましたが、以下は私のコードです

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

javadoc

クラス型Tの変数は、null参照または参照を保持できます TクラスのインスタンスまたはTのサブクラスであるクラスのインスタンスに

ここで作成された匿名オブジェクトのオブジェクトは、Consumerのサブクラスであり、参照変数consumerで参照できます。

しかし、私はConsumerFunctionalInterfaceであるので、私はjava8でこれを行うこともできます -

ラムダの使用

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

またはメソッドリファレンスの使用

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

上記の両方のケースで作成されているサブクラスや匿名クラスはわかりません。

1:ここでconsumerConsumerのサブクラスまたは匿名クラスを参照していない場合、上記のコンセプト変数に違反しているわけではありませんchild/selfまたはnull?

2:lamdasにメモリを割り当てる方法と、実行時にJVMはどのように処理しますか?

  ベストアンサー

まず最初に Jean-Baptiste が示したのは、そもそも課題がうまくいく理由です。

今私が欠けていると思う部分は、Consumer<Integer> consumer = t -> System.out.println(t);の場合に生成されたConsumerのクラスがinvokedynamicのために実行時にのみ表示されるという事実です。

フラグを付けてクラスを実行します。

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

そして、このSOQuestion$$Lambda$1.classのような.classファイルの種類を含む生成されたクラス(クラスのパッケージ名からのフォルダのパス内)があることに気付くでしょう。

実際に Consumer を実装するクラスであることがわかります。

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

ラムダが定義されている生成されたバイトコードを見ると、ラムダ式が実際に静的メソッドにdesugaredされていることがわかります(非capturelambdasの場合、キャプチャラムダの場合は非静的になる可能性があります)。そのためのコード:

 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
 

VMがメモリをどのように管理しているかに関しては、非キャプチャラムダの場合、capturing-lambdaのシングルトンが得られます。各呼び出しの新しいインスタンスが得られます。絶対読み取りはここで

  同じタグがついた質問を見る

javalambdajava-8heap-memory