据我所知Java SE 8
有java.util.Optional<T>
类,可以保护代码免受非预期的null
指针异常的影响。但由于某些原因,我必须使用Java 7
。
看看我的例子:
String version = device.getController().version;
检查device
和getController()
是否为空?
选项1:
String version = "unknown";
if(device!=null){
if(device.getController()!=null)
version = device.getController().version;
}
选项2:
String version = "unknown";
if(device!=null && device.getController()!=null){
version = device.getController().version;
}
选项1有点麻烦,但显然它会正常工作。第二个选项值得怀疑,因为我们不知道哪个条件部分将首先被检查,以及Java
实际上是如何进行检查的。有一点建议Java
在返回结果之前检查2个条件。显然,如果device为null,第二部分将返回NullPointerException
。那么,在Java 7及更早版本中检查嵌套对象的最佳方法是什么?
答案 0 :(得分:1)
第二个选项值得怀疑,因为我们不知道哪个条件部分会先被检查,以及Java实际上是如何做的。
这不是事实。这是一个反事实。
<expr1> && <expr2>
表达式的评估如下:
<expr1>
。<expr1>
的结果为false
,则不会评估<expr2>
。表达式的值为false
。<expr1>
的结果为true
,则评估<expr2>
,这将成为表达式的值。以上是简化版。实际规格在JLS 15.23。
但我的观点是,绝对零不确定性关于如何评估&&
表达式。从Java 1.0开始,每个版本的Java都清晰明确......如果您阅读官方规范和/或官方教程。
您的选项1和2在功能上完全相同。
“最佳”方式是一个意见问题,但我更喜欢选项2,因为它更简洁,同样可读。 (只是我的意见......显然。)
答案 1 :(得分:0)
选项1和选项2功能相同
你可以使用ternary operator因为你提到选项1有点&#34;麻烦&#34;
String version = (device != null && device.getController() != null) ? device.getController().version : "unknown";
答案 2 :(得分:0)
您的第二个选项完全有效。 Java从左到右评估条件。这意味着它将首先评估device!=null
然后评估device.getController()!=null
。
如果发现AND条件(device != null
)的左侧为false,则java将不评估右侧。只会针对device!=null
评估右侧。
答案 3 :(得分:0)
选项2没有问题,首先会检查
device != null
如果这是假的,即设备为空,则不会检查
device.getController()!=null
因为False&amp;&amp; (真/假)是假的
我建议你使用try and catch。
String version = null;
try {
version = device.getController().version;
} catch (NullPointerException ex) {
//log the error here
}