【发布时间】:2026-01-09 22:00:01
【问题描述】:
如果你查看字节码
Consumer<String> println = System.out::println;
Java 8 update 121 生成的字节码是
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
DUP
INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;
POP
INVOKEDYNAMIC accept(Ljava/io/PrintStream;)Ljava/util/function/Consumer; [
// handle kind 0x6 : INVOKESTATIC
java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
// arguments:
(Ljava/lang/Object;)V,
// handle kind 0x5 : INVOKEVIRTUAL
java/io/PrintStream.println(Ljava/lang/String;)V,
(Ljava/lang/String;)V
]
ASTORE 1
正在对System.out 调用getClass() 方法,结果被忽略。
这是间接空引用检查吗?
如果你跑的话当然可以
PrintStream out = null;
Consumer<String> println = out::println;
这会触发 NullPointerException。
【问题讨论】:
-
Peter Lawrey 的问题,Holger 的回答,Shipilev 打开的错误;这个问题让我很开心。
标签: java lambda java-8 javac bytecode