Max*_*lis 21 java eclipse expression compilation ternary-operator
出于某种原因,以下代码正常编译:
public double getSomeDouble() {
return "" != null ? 3.7d : null;
}
Run Code Online (Sandbox Code Playgroud)
我通常希望Eclipse将其标记为错误(null不能转换为double原语).
只是为了支持我的假设,这段代码不起作用:
public double getSomeDouble() {
return null;
}
Run Code Online (Sandbox Code Playgroud)
Eclipse会将该return null行标记为错误,说明:
类型不匹配:无法转换
null为double
为什么它在前面的代码片段中没有说同样的东西?!
T.J*_*der 23
这是由于自动装箱和autounboxing.如果你看一下字节码(下面),你可以看到对Double.valueOf(装箱3.7d)和Double#doubleValue(取消装箱条件表达式的结果)的调用.条件运算符的操作数必须是相同的类型,因此编译器有效地将您的代码转换为:
public double getSomeDouble() {
return ("" != null ? Double.valueOf(3.7d) : null).doubleValue();
}
Run Code Online (Sandbox Code Playgroud)
...因为Double是最具体常见的类型也可以找到3.7d和null.
我使用了一个字符串参数(以消除围绕不变表达式的编译器优化"" != null,编译器能够告诉它永远不会是真的):
public double getSomeDouble(String str) {
return str != null ? 3.7d : null;
}
Run Code Online (Sandbox Code Playgroud)
实际上变成了:
public double getSomeDouble(String str) {
return (str != null ? Double.valueOf(3.7d) : null).doubleValue();
}
Run Code Online (Sandbox Code Playgroud)
......确实得到了在运行时的NPE,当我传入null的str,当它试图调用doubleValue()上null.
这是我getSomeDouble(String)(来自javap -c MyClass)的字节码:
public double getSomeDouble(java.lang.String);
Code:
0: aload_1
1: ifnull 13
4: ldc2_w #7 // double 3.7d
7: invokestatic #9 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
10: goto 14
13: aconst_null
14: invokevirtual #10 // Method java/lang/Double.doubleValue:()D
17: dreturn
| 归档时间: |
|
| 查看次数: |
671 次 |
| 最近记录: |