博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java三元运算和if,Java三元运算符与<JDK8兼容性中的if / else
阅读量:1536 次
发布时间:2019-04-21

本文共 1866 字,大约阅读时间需要 6 分钟。

最近我正在阅读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;

}

}

此方法是类org.springframework.core.MethodParameter的成员。 代码很容易理解,而评论很难。

注意:即使使用JDK 8编译器(可能选择java.lang.reflect.Executable作为常见类型,而新的基类在旧JDK上不可用),也不会保留JDK <8兼容性的三元表达式。

在这种情况下使用三元表达式和使用if...else...构造之间有什么区别?

当你考虑操作数的类型时,问题就会变得更加明显:this.method != null ? this.method : this.constructor

具有两种操作数的最常用类型,即this.method和this.constructor共有的最专用类型。

在Java 7中,这是java.lang.reflect.Member ,但是Java 8类库引入了一种新类型的java.lang.reflect.Executable ,它比通用Member更专业。 因此,对于Java 8类库,三元表达式的结果类型是Executable而不是Member 。

在编译三元运算符时,Java 8编译器的一些(预发布)版本似乎在生成的代码中显式引用了Executable 。 这会触发类加载,并因此在运行时使用类库

正如Tagir Valeev在回答中所指出的那样,这实际上是JDK 8的预发布版本中的一个错误,并且已经被修复,所以if-else解决方法和解释性评论现在都已过时。

补充说明:可能会得出这样的结论:该编译器错误在Java 8之前出现。但是,由OpenJDK 7为三元生成的字节代码与由OpenJDK 8生成的字节代码相同。事实上,表达式在运行时完全没有提到,代码实际上只是测试,分支,加载,返回而没有进行任何额外的检查。 因此,请放心,这不是一个问题(现在已经),而且在Java 8开发过程中似乎确实是一个暂时的问题。

这是在2013年5月3日相当古老的版本中提出的,距JDK-8正式发布差不多一年。 编译器在那个时候处于繁重的开发中,所以可能会出现这种兼容性问题。 我想,Spring团队只是测试了JDK-8构建,并试图解决问题,即使它们实际上是编译器问题。 通过JDK-8官方发布,这变得无关紧要。 现在,此代码中的三元运算符按预期正常工作(不存在对已编译的.class-file中的Executable类的引用)。

目前在JDK-9中出现类似的情况:JDK-8中可以很好编译的代码在JDK-9 javac中失败。 我想,这些问题大部分都会在发布之前得到修复。

主要区别在于if else块是一个语句,而三元(更常称为Java中的条件运算符)是一个表达式。

一条语句可以做一些事情,例如在一些控制路径上return给调用者。 表达式可以用于赋值中:

int n = condition ? 3 : 2;

因此,条件之后的三元表达式需要被强制为相同的类型。 这可能会在Java中引起一些奇怪的效果,特别是在自动装箱和自动引用投射方面 - 这就是您的发布代码中的评论所指的。 在你的情况下,表达式的强制转化为java.lang.reflect.Executable类型(因为这是最专业化的类型),并且在旧版本的Java中不存在。

在风格上,如果代码类似于语句,则应该使用if else块;如果类似表达式,则使用三元。

当然,如果你使用lambda函数,你可以使if else块的行为像表达式一样。

链接地址: http://www.djcxy.com/p/91883.html

转载地址:http://gusdy.baihongyu.com/

你可能感兴趣的文章
电子商务网站放大效果的三种常用的实现方式。
查看>>
前端全栈大佬是如何使用javaScript实现一个焦点图
查看>>
前端全栈大佬是如何使用javaScript实现一个轮播图
查看>>
前端全栈大佬是如何使用javaScript实现一个无缝轮播
查看>>
前端全栈大佬是如何使用javaScript实现一个无缝轮播优化
查看>>
前端全栈大佬是如何使用javaScript实现一个无缝轮播(最终版)
查看>>
小白如何从零开始设计并开发一个微信小程序?
查看>>
孙叫兽VUE学习笔记总结(值得收藏),很全很详细!!!
查看>>
在CSDN的博文中如何添加博主名片
查看>>
2020年末总结,脚踏实地,一步一个脚印——致敬自己一年的心酸历程
查看>>
关于本人在多个技术平台发布文章的声明
查看>>
【面试题系列|前端面试题】前端高频面试题总结(2021年最新版)
查看>>
uniapp去掉右侧滚动条的解决办法?
查看>>
【算法图解|1】js 实现一个函数,完成超过范围的两个大整数相加功能
查看>>
【算法图解|2】JavaScript 如何实现数组扁平化
查看>>
【算法图解|3】JavaScript 如何实现数组去重
查看>>
【算法图解|4】JavaScript 如何求数组的最大值和最小值
查看>>
【算法图解|5】javaScript求两个数的最大公约数
查看>>
JavaScript 如何求两个数的最小公倍数
查看>>
孙叫兽带你了解腾讯位置服务的认证与接入,多种行业方案参考!
查看>>