在java中检查String/Object的空值?
什么是具有在java中检查String/Object的空值?
String a = null;
if(null != a)
的优势超过
if(a !=null)
我都尝试声明,他们工作得很好。任何建议为什么我应该去第一个?
这听起来更自然,首先将问题置于问题之下。
英语中你会说,“如果答案是正确的,然后检查”。你不会说,“如果正确答案”。人们用自己的想法和说话来编码。
切换订单(我知道)的唯一有效用例是您要拨打的地方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;
}
}
差异均在误差范围内。 – shmosel
看到这个答案的评论。有一些关于** yoda比较的讨论** http://stackoverflow.com/a/35720897/1737819 – Willmore
http://stackoverflow.com/questions/35727244/positioning-primitive-before-operator-and-not-after -it#comment59129359_35727244 – Tom
这实际上可能会影响JIT和CPU分支预测优化,所以确实可能会有性能差异。如果调用数千次,它可能会影响纳秒。 – rjdkolb