在Java中检查空值的最佳方法?

在Java中检查空值的最佳方法?,java,null,nullpointerexception,Java,Null,Nullpointerexception,在调用对象的函数之前,我需要检查对象是否为null,以避免抛出NullPointerException 最好的办法是什么?我考虑过这些方法 哪一种是Java的最佳编程实践 // Method 1 if (foo != null) { if (foo.bar()) { etc... } } // Method 2 if (foo != null ? foo.bar() : false) { etc... } // Method 3 try { i

在调用对象的函数之前,我需要检查对象是否为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...
}

最后也是最好的。i、 e逻辑与

  if (foo != null && foo.bar()) {
    etc...
}
因为在逻辑
&

没有必要知道右手边是什么,结果一定是假的


喜欢阅读:

方法4是最好的。

if(foo != null && foo.bar()) {
   someStuff();
}
将使用,这意味着如果
逻辑AND的第一个条件为false,则结束。

  • 不要捕获
    NullPointerException
    。这是一种糟糕的做法。最好确保该值不为null
  • 方法4适合你。它不会计算第二个条件,因为Java存在短路(即,如果后续条件不改变布尔表达式的最终结果,则不会计算后续条件)。在这种情况下,如果逻辑AND的第一个表达式的计算结果为false,则不需要计算后续表达式

我想说方法4是我看过的代码中最通用的习惯用法。但我总觉得这有点难闻。它假定foo==null与foo.bar()==false相同


我觉得这并不总是对的。

方法4是我首选的方法。&&运算符的短路使代码最具可读性。方法3,捕获NullPointerException,在大多数情况下,当一个简单的空检查就足够的时候,是不受欢迎的。

方法4是最好的,因为它清楚地指出了将发生什么,并且使用了最少的代码

方法3在每个层面上都是错误的。你知道这个项目可能是空的,所以这不是一个例外情况,这是你应该检查的

方法2只是让它变得比需要的更复杂


方法1只是方法4,有一行额外的代码。

如果您没有访问commons apache库的权限,下面的方法可能可以使用

if(null != foo && foo.bar()) {
//do something
}

你最后的建议是最好的

if (foo != null && foo.bar()) {
    etc...
}
因为:

  • 它更容易阅读
  • 这是安全的:如果foo==null,则永远不会执行foo.bar()
  • 它可以防止诸如捕获NullPointerException之类的错误做法(大多数情况下是由于代码中的错误)
  • 它的执行速度应该和其他方法一样快,甚至更快(尽管我认为几乎不可能注意到它)

  • 如果您控制调用的API,请考虑使用

    更多信息。将方法更改为返回一个
    可选
    ,而不是一个
    布尔值


    这会通知调用代码它必须考虑null的可能性,通过调用
    Optional

    中的一个简便方法,在Java 7中,您可以使用
    Objects.requirennull()
    。 从
    java.util
    添加
    对象的导入

    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");
        }
        //...
    }
    
    正如其他人所说,当不使用库方法时,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){
    

    我们可以使用Object.requireNonNull对象类的静态方法。执行情况如下

    public void someMethod(SomeClass obj) {
        Objects.requireNonNull(obj, "Validation error, obj cannot be null");
    }
    

    检查空值的简单单行代码:

    namVar == null ? codTdoForNul() : codTdoForFul();
    

    您还可以使用
    StringUtils.isNoneEmpty(“”)
    检查是否为null或空。

    如果您要使用双相等“==”进行检查,则使用对象ref-like检查null

    if(null == obj) 
    
    而不是

    if(obj == null)
    
    因为如果您错误地键入了single equal if(obj=null),它将返回true(赋值对象返回success(值为true)。

    对于java 11+,您可以使用


    永远不要捕获空指针异常。它属于“Boneheaded异常”类别,具体取决于您的用例,如果
    null
    foo
    被传递给您的方法,则禁止
    null
    值,并抛出
    NullPointerException
    也是有意义的。1)1和4之间的差异是一种风格选择,充其量只是一种微观优化。2) 只要你不允许抛出异常,这其实并不重要,与其担心哪种异常最适合使用,不如把时间花在清晰的设计/更好的算法上。@assylias
    IllegalArgumentException
    应该用在这种情况下。@NickFreeman我不同意-参见示例:-标准(在JDK、番石榴和有效Java中)就是抛出一个NPE。虽然IAE在这种情况下也被普遍使用。谢谢,我认为这是最好的,但我不确定为什么它不会调用第二个条件,或者有时可能会调用第二个条件-谢谢你解释为什么。是的,因为你使用的是短路操作数-&所以它不会完成整个过程expression@Arty-菲什那是这始终是一个好问题,因为它依赖于语言-通常类似C的语言倾向于从左到右短路,但并非所有语言都是如此,最好先检查;)值得一提的是,捕获空指针异常是一种不好的做法;例外情况非常昂贵,即使是少数例外情况也会使您的速度减慢code@RichardTingle在大多数情况下,异常的代价是可以忽略的(java到处都在使用它们),更重要的是,NullpointerException不仅可以来自foo,还可以来自try{和}之间的任何地方捕捉,以便通过捕捉来隐藏错误it@josefx做(几乎)任何事情的成本都可以忽略不计,显然,只有当代码中的部分是瓶颈时,它才有意义;然而,如果是这样的话,很可能就是原因。我收集了一些数据来回答这个问题。显然,这也是一个坏主意,因为你提到的原因(除此之外还有很多其他原因)。也许我应该说“原因之一”而不是“原因”@理查丁格尔例外情况并非如此
    if(nonNull(foo)){ 
    //
    }