在java中检查String/Object的空值?

问题描述:

什么是具有在java中检查String/Object的空值?

String a = null; 
if(null != a) 

的优势超过

if(a !=null) 

我都尝试声明,他们工作得很好。任何建议为什么我应该去第一个?

+4

看到这个答案的评论。有一些关于** yoda比较的讨论** http://stackoverflow.com/a/35720897/1737819 – Willmore

+0

http://stackoverflow.com/questions/35727244/positioning-primitive-before-operator-and-not-after -it#comment59129359_35727244 – Tom

+0

这实际上可能会影响JIT和CPU分支预测优化,所以确实可能会有性能差异。如果调用数千次,它可能会影响纳秒。 – rjdkolb

两者是相同的,但是如果你是一个布尔值检查==

if(a == true) 

VS

if(true == a) 

后者将通过键入更好,由于印刷上的错误倾向只有=而不是==

if(a = true) //still compilable but not what you intended 
if(true = a) //cannot be compiled, hence you know you typed it wrongly 
+0

在C(++)中它很有用。 – Koshinae

+1

它编译,因为'a'已经是布尔值了。 – Koshinae

这听起来更自然,首先将问题置于问题之下。

英语中你会说,“如果答案是正确的,然后检查”。你不会说,“如果正确答案”。人们用自己的想法和说话来编码。

切换订单(我知道)的唯一有效用例是您要拨打的地方equals()但您正在测试的对象可能为空。在这种情况下,它可以清洁剂来做

if ("expected".equals(value)) 

if (value != null && value.equals("expected")) 

嘛,没什么除了(缺乏)的可读性。

此外,它仅适用于布尔类型:

boolean b = true; 
if (b) { 
    System.out.println("b, it is"); // << this 
} else { 
    System.out.println("not b"); 
} 

让我们破解:

boolean b = false; 
if (b = true) { 
    System.out.println("b, it is"); // << this 
} else { 
    System.out.println("not b"); 
} 

其他方式:

boolean b = true; 
if (b = false) { 
    System.out.println("b, it is"); 
} else { 
    System.out.println("not b"); // << this 
} 

但随着一个int:

int a = 5; 
if(a = 0) { // error: incompatible types: int cannot be converted to boolean 
    System.out.println("0"); 
} else { 
    System.out.println("not 0"); 
} 

在您的示例中,使用String和a = null表达式也是如此。所以虽然这个Yoda比较在C中很有用,但在Java中是没用的。

优点: 在表达式中放置常量不会改变程序的行为(除非值的计算结果为false)。在使用单个等号(=)进行赋值而不是用于比较的编程语言中,可能的错误是无意中赋值而不是写入条件语句。

性能: 对服务表现无影响

可读性:其下降

缺点避免空行为的优点,也被认为是一个缺点,因为空指针错误可以被隐藏并且只在程序中出现很久。

好像有一个微小区别。 使用JMH在SecureRandom测试和随机测试之间看起来很小。我认为这种差异并不重要。

Benchmark              Mode Samples Score Score error Units 
c.g.v.YodaCompPerformace.countNullsArrayList     thrpt  200 1.345  0.009 ops/ms 
c.g.v.YodaCompPerformace.countNullsArrayListSecureRandom  thrpt  200 1.349  0.008 ops/ms 
c.g.v.YodaCompPerformace.countNullsArrayListSecureRandomYoda thrpt  200 1.358  0.009 ops/ms 
c.g.v.YodaCompPerformace.countNullsArrayListYoda    thrpt  200 1.361  0.009 ops/ms 

JHM代码:

import java.security.SecureRandom; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.TimeUnit; 
import org.openjdk.jmh.annotations.Benchmark; 
import org.openjdk.jmh.annotations.Level; 
import org.openjdk.jmh.annotations.OutputTimeUnit; 
import org.openjdk.jmh.annotations.Scope; 
import org.openjdk.jmh.annotations.Setup; 
import org.openjdk.jmh.annotations.State; 

@OutputTimeUnit(TimeUnit.MILLISECONDS) 
@State(Scope.Thread) 
public class YodaCompPerformace { 

    static List<Integer> arrayListSecureRandom; 
    static List<Integer> arrayListRandom; 

    @Setup(Level.Iteration) 
    public void setUpSecureRandom() { 
     arrayListSecureRandom = new ArrayList<>(100000); 
     for (int count = 0; count < 100000; count++) { 
      if ((count & 1) == 0) { 
       arrayListSecureRandom.add(count); 
      } else { 
       arrayListSecureRandom.add(null); 
      } 
     } 
     Collections.shuffle(arrayListSecureRandom, new SecureRandom()); 
    } 

    @Setup(Level.Iteration) 
    public void setUp() { 
     arrayListRandom = new ArrayList<>(100000); 
     for (int count = 0; count < 100000; count++) { 
      if ((count & 1) == 0) { 
       arrayListRandom.add(count); 
      } else { 
       arrayListRandom.add(null); 
      } 
     } 
     Collections.shuffle(arrayListRandom, new Random()); 
    } 
    @Benchmark 
    public int countNullsArrayListSecureRandom() { 
     int countNulls = 0; 
     for (Integer i : arrayListSecureRandom) { 
      if (i == null) { 
       countNulls++; 
      } 
     } 
     return countNulls; 
    } 
    @Benchmark 
    public int countNullsArrayListSecureRandomYoda() { 
     int countNulls = 0; 
     for (Integer i : arrayListSecureRandom) { 
      if (null == i) { 
       countNulls++; 
      } 
     } 
     return countNulls; 
    } 
    @Benchmark 
    public int countNullsArrayList() { 
     int countNulls = 0; 
     for (Integer i : arrayListSecureRandom) { 
      if (i == null) { 
       countNulls++; 
      } 
     } 
     return countNulls; 
    } 
    @Benchmark 
    public int countNullsArrayListYoda() { 
     int countNulls = 0; 
     for (Integer i : arrayListSecureRandom) { 
      if (null == i) { 
       countNulls++; 
      } 
     } 
     return countNulls; 
    } 

} 
+0

差异均在误差范围内。 – shmosel