在Java Lambda';这就是为什么对捕获的变量调用getClass()
如果你看一下在Java Lambda';这就是为什么对捕获的变量调用getClass(),java,lambda,java-8,javac,bytecode,Java,Lambda,Java 8,Javac,Bytecode,如果你看一下 Consumer<String> println = System.out::println; 正在对系统.out调用getClass()方法,结果被忽略 这是间接空引用检查吗 当然,如果你跑的话 PrintStream out = null; Consumer<String> println = out::println; PrintStream out=null; 消费者println=out::println; 这会触发NullPointerEx
Consumer<String> println = System.out::println;
正在对系统.out
调用getClass()
方法,结果被忽略
这是间接空引用检查吗
当然,如果你跑的话
PrintStream out = null;
Consumer<String> println = out::println;
PrintStream out=null;
消费者println=out::println;
这会触发NullPointerException。是的,调用
getClass()
已经成为一种规范的“测试null
”习惯用法,因为getClass()
被认为是一种廉价的内在操作,我想,如果未使用getClass()
的结果,HotSpot可能能够检测此模式并将操作减少为内在的null
-check操作
另一个例子是创建一个内部类实例,而外部实例不是this
:
public class ImplicitNullChecks {
class Inner {}
void createInner(ImplicitNullChecks obj) {
obj.new Inner();
}
void lambda(Object o) {
Supplier<String> s=o::toString;
}
}
谢谢你,你的见解一如既往地很有价值。如果只需要一条空校验字节码指令就好了。@David Conrad:这并不经常需要,而且专用校验指令相对于一条调用指令(对于一个众所周知的方法)的优势并没有那么大。作为一个净好处,如果JVM识别
对象.requirennull
并从本质上处理这些调用,那么显式调用它的Java代码也会从中受益。@holi Java:我不确定,您希望使用哪种外部引用。每个人都可以验证讨论过的编译表单,例如,使用,引用的JDK-8073550
已经链接,如果您想更深入,您可以从讨论开始并遵循讨论。@Lii我注意到已经覆盖了它。不幸的是,除非此功能专门处理Objects.requirennoull
并分析调用者,否则它在这里没有帮助。outer.new Inner()
示例就在这里,在我的回答中;这个问题肯定让我高兴。
public class ImplicitNullChecks {
class Inner {}
void createInner(ImplicitNullChecks obj) {
obj.new Inner();
}
void lambda(Object o) {
Supplier<String> s=o::toString;
}
}
Compiled from "ImplicitNullChecks.java"
public class bytecodetests.ImplicitNullChecks {
public bytecodetests.ImplicitNullChecks();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
void createInner(bytecodetests.ImplicitNullChecks);
Code:
0: new #23 // class bytecodetests/ImplicitNullChecks$Inner
3: dup
4: aload_1
5: dup
6: invokevirtual #24 // Method java/lang/Object.getClass:()Ljava/lang/Class;
9: pop
10: invokespecial #25 // Method bytecodetests/ImplicitNullChecks$Inner."<init>":(Lbytecodetests/ImplicitNullChecks;)V
13: pop
14: return
void lambda(java.lang.Object);
Code:
0: aload_1
1: dup
2: invokevirtual #24 // Method java/lang/Object.getClass:()Ljava/lang/Class;
5: pop
6: invokedynamic #26, 0 // InvokeDynamic #0:get:(Ljava/lang/Object;)Ljava/util/function/Supplier;
11: astore_2
12: return
}
Compiled from "ImplicitNullChecks.java"
public class bytecodetests.ImplicitNullChecks {
public bytecodetests.ImplicitNullChecks();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
void createInner(bytecodetests.ImplicitNullChecks);
Code:
0: new #26 // class bytecodetests/ImplicitNullChecks$Inner
3: dup
4: aload_1
5: dup
6: invokestatic #27 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
9: pop
10: invokespecial #28 // Method bytecodetests/ImplicitNullChecks$Inner."<init>":(Lbytecodetests/ImplicitNullChecks;)V
13: pop
14: return
void lambda(java.lang.Object);
Code:
0: aload_1
1: dup
2: invokestatic #27 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
5: pop
6: invokedynamic #29, 0 // InvokeDynamic #0:get:(Ljava/lang/Object;)Ljava/util/function/Supplier;
11: astore_2
12: return
}