开发者

What is the value of the test !"".equals(someString)

In a project I've been trying to familiarise myself with, I ran across a method that looks like this:

public boolean testString(String string){
    return string != null && !"".equals(string);
}

What is the value of testing the string for emptiness this way instead of with the variable first? I understand why we see constant-first (Yoda syntax) in C, but is there any reason to do so with m开发者_JAVA技巧ethod calls in Java?

note: I do understand about NullPointerException, which is not possible in this instance. I'm looking for a value to doing it this way in this case particularly.


In this context it makes little difference, as it already tested for null. Usually you do it this way to make sure you don't call a member on a null-reference (resulting in a NullPointerException), i.e.

"test".equals(myString)

will never throw a null pointer exception whereas

myString.equals("test")

will if myString is null. So basically, the first test makes sure it's a string (not null) AND it's equal to "test".


For two strings it doesn't matter much, but when there is a non-final type involved it can be a micro-optimization.

If the left hand side is a non-overridden concrete type, then the dispatch becomes static.

Consider what the JIT has to do for

Object o;
String s;

o.equals(s)

vs

s.equals(o)

In the first, the JIT has to find the actual equals method used, whereas in the second, it knows that it can only by String.equals.

I adopted the habit of doing

"constant value" == variableName

in other languages, since it means that the code will fail to parse if I mis-type = instead of ==. And when I learned Java, I kept that order preference.


The usual reason for using "constant string".equals(variable) is that this works properly even if variable is null (unlike variable.equals("constant string")). In your case, however, since you are testing that string != null in a short-circuit boolean test, it's entirely a matter of style (or habit).


If they just did this:

!"".equals(string);

then they're avoiding the possibility of a NullPointerException, which is pretty smart. However, they're checking for null right before this condition, which is technically not necessary.


Is it running any tools like checkstyle? if it is, putting the variable first will result in checkstyle failing. Another reason is that if you put the empty string first it will take away the possibility of getting a null exception if the variable is null because the expression will always evaluate to false. If you had the variable first and the variable was null it will throw an exception.


It is more than a coder preference. If the purpose of the method was only to check that string is not an empty String (without caring whether its a null) then it makes sense to have the constant first to avoid a NullPointerException. e.g. This method will return the boolean outcome. false in case string is null.

public boolean testString(String string){
    return !"".equals(string);
}

while this one may throw a runtime exception if string is null

public boolean testString(String string){
    return !string.equals("");
}


No, it is unnatural, and harder to read. It triggers a pause for most readers, and may wastefully consume lots of resources on stackoverlow.com.

(Better use string.isEmtpy() anyway)

There are no fixed rules tho, sometime this is easier to read

if( null != foobar(blahblahblah, blahblahblah, blahblahblah) )

than

if( foobar(blahblahblah, blahblahblah, blahblahblah) != null )


This question can be answered on a number of levels:

  1. What does the example mean?

    As other answers have explained, !"".equals(str) tests if str is an non-empty string. In general, the <stringLiteral>.equals(str) idiom is a neat way of testing a string that deals with the null case without an explicit test. (If str is null then the expression evaluates to false.

  2. Is this particular example best practice?

    In general no. The !"".equals(str) part deals with the case where str is null, so the preceding null test is redundant.

    However, if str was null in the vast majority of cases, this usage would possibly be faster.

  3. What is a better way to do this from a code-style perspective?

    return "".equals(str);

    or

    return str != null && !str.isEmpty();

    However, the second approach doesn't work with Java versions prior to 1.6 ... because isEmpty() is a recent API extension.

  4. What is the optimal way to do this?

    My gut feeling is that return str != null && !str.isEmpty(); will be fastest. The String.isEmpty() method is implemented as a one-line test, and is small enough that the JIT compiler will inline it. The String.equals(Object) method is a lot more complicated, and too big to be inlined.


Miško Hevery (see his videos on youtube) calls this type of overkill "paranoid programming" :-)

Probably in this video: http://www.youtube.com/watch?v=wEhu57pih5w

See also here: http://misko.hevery.com/2009/02/09/to-assert-or-not-to-assert/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜