-1

I understand and know why you typically have to use == to compare strings in java, but for some reason I am able to do it in Eclipse. My code is Code:

public class Test{
    public static void main(String [] args){
        String str1 = "string";
        if(str1 == "string"){
            System.out.println("wtf");
        }
    }
}

Why does this print "wtf" yet using javac from command line does not?

inuasha
  • 23
  • 8
  • 2
    The behavior is nondeterministic -- sometimes it works, sometimes it doesn't -- and that's **exactly why** it's contrary to best practices. – Charles Duffy May 04 '14 at 22:43
  • is this not the millionth time this question has been asked? And the way you ask it suggests that you do *not* know when you should use == – Amir Afghani May 04 '14 at 22:44
  • 1
    @CharlesDuffy He's asking why it doesn't work in the command line, but does in Eclipse. – Michael Yaworski May 04 '14 at 22:47
  • @mikeyaworski ...and see again, "nondeterministic" (though that's not strictly true; "unspecified" is the more accurate word). That said, I actually disbelieve the claim that this exact code fails when invoked from the CLI -- hardcoded strings should always be interned. – Charles Duffy May 04 '14 at 22:55
  • 3
    Actually, the JLS specifies that all String literals are interned (http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5). This code should be perfectly legitimate and deterministic. That comparison should return true, according to the JLS. I'm having difficulty believing that javac from the command line doesn't print `wtf` here. – Dawood ibn Kareem May 04 '14 at 22:57
  • 1
    Just tried with both Eclipse and `javac 1.8.0`, got `wtf` for both – awksp May 04 '14 at 23:12
  • This should work universally. More likely, the class you are running from the command line is out of date and doesn't match the code you're showing here. Try deleting the class file then recompiling to ensure the class file matches the code. Consider also you classpath; maybe there's an old copy of the class earlier in the classpath - again the fix is to find all class files and delete them. – Bohemian May 04 '14 at 23:55
  • @CharlesDuffy I was replying to your duplicate claim. I just don't agree that it's a duplicate. – Michael Yaworski May 04 '14 at 23:58
  • Seriously? After all this discussion, more people have voted to close this as a duplicate? It quite obviously is no such thing. Of course, it should probably be closed as "unreproduceable", until such time as the OP provides clarification. – Dawood ibn Kareem May 05 '14 at 03:20

2 Answers2

5

Eclipse allows you to compare references because it is a legitimate comparison. Just probably not the one you really want.

Because of String interning it will sometimes appear to work, but you should not rely upon it unless you know the strings you're comparing have been interned. The correct way to compare Strings for equal value is to use .equals.

Don Roby
  • 40,677
  • 6
  • 91
  • 113
  • Indeed, you shouldn't. I'll add a clarification. – Don Roby May 04 '14 at 22:44
  • I understand this, but it always works. It never doesn't work. No matter how many times I run the code it always works. – inuasha May 04 '14 at 22:47
  • 5
    @inuasha the Java language guarantees that compile time constant strings (typically quoted string literals) are interned, so `"foo" == "foo"` is always true but `new String("foo") == new String("foo")` is not. – Ian Roberts May 04 '14 at 22:49
  • 3
    It always works in this particular code because string literals are always interned, and you've used the same string literal in both places. – Don Roby May 04 '14 at 22:49
  • 1
    Contrary to your second paragraph, there is absolutely no reason not to rely on `==` to compare String literals. The JLS guarantees that it will work. – Dawood ibn Kareem May 04 '14 at 23:25
  • Ok. Revised that paragraph. – Don Roby May 04 '14 at 23:30
  • Agreed with @DavidWallace. However, when I take advantage of this, I usually add a comment to avoid future confusion, e.g., `// var will be identity-equal to one of these string literals`. – Kevin Krumwiede May 05 '14 at 01:54
0

It allow cause it probably faster to compare two address than comparing 2 string (but use it with caution, you probably never have to compare two String address).

It is sometime usefull to compare Object memories address, and as long as String is an object, eclipse allow you to compare using ==

Anthony Raymond
  • 7,434
  • 6
  • 42
  • 59