2016-03-03 66 views
1

什麼是具有在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

回答

4

兩者是相同的,但是如果你是一個布爾值檢查==

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

1

這聽起來更自然,首先將問題置於問題之下。

英語中你會說,「如果答案是正確的,然後檢查」。你不會說,「如果正確答案」。人們用自己的想法和說話來編碼。

切換訂單(我知道)的唯一有效用例是您要撥打的地方equals()但您正在測試的對象可能爲空。在這種情況下,它可以清潔劑來做

if ("expected".equals(value)) 

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

嘛,沒什麼除了(缺乏)的可讀性。

此外,它僅適用於布爾類型:

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中是沒用的。

1

優點: 在表達式中放置常量不會改變程序的行爲(除非值的計算結果爲false)。在使用單個等號(=)進行賦值而不是用於比較的編程語言中,可能的錯誤是無意中賦值而不是寫入條件語句。

性能: 對服務表現無影響

可讀性:其下降

缺點避免空行爲的優點,也被認爲是一個缺點,因爲空指針錯誤可以被隱藏並且只在程序中出現很久。

0

好像有一個微小區別。 使用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