简体   繁体   中英

Checking null value for a String/Object in java?

What are the advantages of having

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

over

if(a !=null)

I tried both statement and they worked fine. Any suggestions why should I go with the first one?

Both are the same, however if you are checking for == on a boolean value:

if(a == true)

vs

if(true == a)

The latter would be better due to the tendency of typographical error by typing only = instead of == :

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

It just sounds more natural to put the item under question first.

In English you would say, "if answer is correct then check". You wouldn't say, "if correct is answer". People code the way they think and speak.

The only valid use case to switch the order (that I'm aware of) is where you're calling equals() but the object you're testing may be null. In such a case, it can be cleaner to do

if ("expected".equals(value))

than

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

Advantage : Placing the constant value in the expression does not change the behavior of the program (unless the values evaluate to false). In programming languages that use a single equals sign (=) for assignment and not for comparison, a possible mistake is to assign a value unintentionally instead of writing a conditional statement.

Performance: No impact on performace

Readability: Its decreased

Cons The advantage of avoiding null behavior can also be considered a disadvantage, as null pointer errors can be hidden and only appear much later in the program.

Well, nothing besides (the lack of) readability.

Also, it only works with boolean types:

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

Let's hack:

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

Other way around:

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

But with an 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");
}

Same happens in your example, with a String and the a = null expression. So while this Yoda Comparison is useful in C, it is useless in Java.

It seems like there is a tiny difference. Using JMH there seems tiny difference between in the SecureRandom test and random test. The difference is not significant in my opinion.

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 code :

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;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM