jdd*_*dxf 112 java ternary-operator java-8
最近我正在阅读Spring Framework的源代码.我无法理解的东西在这里:
public Member getMember() {
// NOTE: no ternary expression to retain JDK <8 compatibility even when using
// the JDK 8 compiler (potentially selecting java.lang.reflect.Executable
// as common type, with that new base class not available on older JDKs)
if (this.method != null) {
return this.method;
}
else {
return this.constructor;
}
}
Run Code Online (Sandbox Code Playgroud)
此方法是类的成员org.springframework.core.MethodParameter
.代码很容易理解,而评论很难.
注意:即使使用JDK 8编译器,也没有三元表达式来保持JDK <8的兼容性(可能选择
java.lang.reflect.Executable
为通用类型,旧的JDK上没有新的基类)
if...else...
在这种情况下使用三元表达和使用构造有什么区别?
dhk*_*hke 102
当您考虑操作数的类型时,问题变得更加明显:
this.method != null ? this.method : this.constructor
Run Code Online (Sandbox Code Playgroud)
有类型两个操作数的最专业的常见类型,即两者共同的最专业的类型this.method
和this.constructor
.
java.lang.reflect.Member
然而,在Java 7中,Java 8类库引入了一种java.lang.reflect.Executable
比泛型更专业的新类型Member
.因此,对于Java 8类库,三元表达式的结果类型Executable
不是Member
.
Executable
在编译三元运算符时,Java 8编译器的某些(预发布)版本似乎已生成对内部生成代码的显式引用.这将触发类加载,因此在ClassNotFoundException
运行时使用类库<JDK 8进行运行,因为Executable
仅存在JDK≥8.
正如Tagir Valeev在本回答中所指出的,这实际上是JDK 8预发布版本中的一个错误,并且已经修复,因此if-else
解决方法和解释性注释现在都已过时.
附加说明:有人可能得出结论,这个编译器错误出现在Java 8之前.但是,OpenJDK 7为三元生成的字节代码与OpenJDK 8生成的字节代码相同.实际上,类型为表达式在运行时完全没有提及,代码实际上只是测试,分支,加载,返回而不进行任何额外的检查.所以请放心,这不再是问题(在Java 8的开发过程中确实似乎是一个临时问题).
Tag*_*eev 30
这是在2013年5月3日相当旧的提交中引入的,差不多在官方JDK-8发布之前一年.编译器在那些时候处于大量开发阶段,因此可能会出现这种兼容性问题.我猜,Spring团队刚刚测试了JDK-8版本并尝试修复问题,即使它们实际上是编译器问题.通过JDK-8官方发布,这变得无关紧要.现在,此代码中的三元运算符正常工作(没有引用Executable
编译的.class文件中的类).
目前在JDK-9中出现了类似的东西:JDK-8中可以很好地编译的一些代码在JDK-9 javac中失败了.我猜,大多数此类问题将在发布之前修复.
主要区别在于if
else
块是一个语句,而三元(通常称为Java中的条件运算符)是一个表达式.
一言可以做这样的事情return
对某些控制路径的调用者.的表达可以在分配中使用:
int n = condition ? 3 : 2;
因此条件之后的三元中的两个表达式需要可强制转换为相同类型.这可能会导致Java中的一些奇怪的效果,尤其是自动装箱和自动参考投射 - 这就是您发布的代码中的注释所指的内容.在您的情况下,表达式的强制将是一种java.lang.reflect.Executable
类型(因为它是最专业的类型),并且在旧版本的Java中不存在.
从风格上讲,if
else
如果代码类似于语句,则应使用块,如果类似于表达式,则应使用三元组.
当然,if
else
如果使用lambda函数,则可以使块的行为类似于表达式.
归档时间: |
|
查看次数: |
10060 次 |
最近记录: |