在Java中检查空值的最佳方法是什么?
在调用对象的函数之前,我需要检查对象是否为null,以避免抛出NullPointerException
。
最好的方法是什么? 我考虑过这些方法。
哪一个是Java的最佳编程实践?
// Method 1 if (foo != null) { if (foo.bar()) { etc... } } // Method 2 if (foo != null ? foo.bar() : false) { etc... } // Method 3 try { if (foo.bar()) { etc... } } catch (NullPointerException e) { } // Method 4 -- Would this work, or would it still call foo.bar()? if (foo != null && foo.bar()) { etc... }
方法4是最好的。
if(foo != null && foo.bar()) { someStuff(); }
将使用短路评估 ,这意味着如果logical AND
的第一个条件为假,它将结束。
最后也是最好的一个。 即逻辑和
if (foo != null && foo.bar()) { etc... }
因为在逻辑&&
没有必要知道右手边是什么,结果必须是假的
更喜欢阅读: Java逻辑运算符短路
在Java 8中,检查null的最佳方法是:
Objects.isNull(obj) //returns true if the object is null Objects.nonNull(obj) //returns true if object is not-null if(Objects.nonNull(foo) && foo.something()) // Uses short-circuit as well. No Null-pointer Exceptions are thrown.
除此之外……您还可以选择Guava的Optional Class
减少类似于(obj=null)
的类型错误,它总是返回true
如前面的答案所述。
- 不要捕获
NullPointerException
。 这是一种不好的做法。 最好确保该值不为null。 - 方法#4适合你。 它不会评估第二个条件,因为Java有短路(即,如果它们不改变布尔表达式的最终结果,则不会评估后续条件)。 在这种情况下,如果逻辑AND的第一个表达式求值为false,则不需要计算后续表达式。
方法4是最好的,因为它清楚地表明将发生什么并使用最少的代码。
方法3在每个级别都是错误的。 你知道这个项目可能是null所以这不是一个特殊的情况,你应该检查它。
方法2只是让它变得比它需要的更复杂。
方法1只是方法4,带有额外的代码行。
我会说方法4是我看过的代码中最常用的习语。 但这对我来说总觉得有点臭。 假设foo == null与foo.bar()== false相同。
这对我来说并不总是合适。
方法4是我的首选方法。 &&运算符的短路使代码最具可读性。 方法3,捕获NullPointerException,在大多数时候只需要一个简单的空检查即可。
在Java 7中 ,您可以使用Objects.requireNonNull()
。 从java.util
添加Objects
类的导入。
public class FooClass { //... public void acceptFoo(Foo obj) { //If obj is null, NPE is thrown Objects.requireNonNull(obj).bar(); //or better requireNonNull(obj, "obj is null"); } //... }
如果您控制被调用的API,请考虑使用Guava的Optional类
更多信息在这里 。 更改方法以返回Optional
而不是Boolean
。
这通过调用Optional
一个方便方法,通知调用代码它必须考虑null的可能性
正如其他人所说,#4是不使用库方法的最佳方法。 但是,您应该始终在比较的左侧放置null,以确保在输入错误时不会意外地将null赋给foo。 在这种情况下,编译器将捕获错误。
// You meant to do this if(foo != null){ // But you made a typo like this which will always evaluate to true if(foo = null) // Do the comparison in this way if(null != foo) // So if you make the mistake in this way the compiler will catch it if(null = foo){ // obviously the typo is less obvious when doing an equality comparison but it's a good habit either way if(foo == null){ if(foo = null){
您还可以使用StringUtils.isNoneEmpty("")
进行检查为空或空。
你的最后一个提案是最好的。
if (foo != null && foo.bar()) { etc... }
因为:
- 它更容易阅读。
- 这是安全的:如果foo == null,永远不会执行foo.bar()。
- 它可以防止诸如捕获NullPointerExceptions之类的错误操作(大部分时间是由于代码中的错误)
- 它应该比其他方法执行得更快甚至更快(尽管我认为几乎不可能注意到它)。
如果您无法访问commons apache库,则以下内容可能正常
if(null != foo && foo.bar()) { //do something }
我们可以使用Object类的Object.requireNonNull静态方法。 实施如下
public void someMethod(SomeClass obj) { Objects.requireNonNull(obj, "Validation error, obj cannot be null"); }
简单的一行代码检查null:
namVar == null ? codTdoForNul() : codTdoForFul();
如果你要用双等号“==”检查,那么用对象ref检查null
if(null == obj)
代替
if(obj == null)
因为如果你错误输入单个等于if(obj = null)它将返回true(赋值对象返回成功(值为’true’)。