2

The following question is from a quiz I took a few weeks ago and got incorrect, but the answer wasn't provided:

Consider the following code, which contains no compile errors:

String secret = "Ellie";
Scanner kb = new Scanner(System.in);
System.out.println("Guess which name I'm thinking of:");
String guess = kb.next();

if (guess == secret)
{
    System.out.println("Wow! You're smart!");
}
else
{
    System.out.println("Wrong!");
    System.out.println("You guessed: " + guess);
    System.out.println("The correct answer was: " + secret);
}

Suppose the user enters "Ellie" at the prompt. What output would result, and why that output and not the other output?

Here was my incorrect answer:

The output would be the else statement "WRONG!" because of the capitalization of the letter 'E'. A solution to this would be to either change the String secret to "ellie" as well as the user's guess, or one can write in the ignoreCase keyword to String secret.

The program actually outputs "Wrong", I tested it.

Aside from simply knowing the answer, could someone really explain this to me so I can understand the concept better?

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
Alex Moss
  • 161
  • 4
  • 11
  • You were right with your answer except for the wrong reason, it actually has to do with the `guess == secret` part. – Marcelo Aug 10 '11 at 23:13
  • `equalsIgnoreCase` would be used to compare "Ellie" and "eLLie" and still get `true`. `equals` would be enough to compare "Ellie" and "Ellie". – Jeffrey Aug 10 '11 at 23:18

2 Answers2

8

The == does a reference comparison, and so it'll always say 'Wrong!', even if the two string references are equal. In order for it to match correctly, it would have to use secret.equals( guess ).

Shawn D.
  • 7,895
  • 8
  • 35
  • 47
  • 2
    That's actually not quite right. You will not always get "Wrong!". The JVM might decide to reuse the "Ellie" string instance, in which case you would get a correct. The behavior is simply undefined. – Chronial Aug 10 '11 at 23:31
  • Point taken. Any idea the chances this happens? – Shawn D. Aug 10 '11 at 23:48
  • I assume it is actually quite likely, but i'm not sure. If you really want to know, writing a little program to test that shouldn't be to difficult ;). – Chronial Aug 10 '11 at 23:50
  • @Chronial: Actually, this is quite defined in the [language specification](http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#19369). All equal string literals and other string compile time constants are also identical objects. Also, everything which got `intern()`ed is identical to these. Strings created by `new` are new objects, not identical to anything existing before. Strings read in from the user quite likely fresh strings (but this depends on the implementation of the scanner's `next` method here - it could call `intern`, though this would not be a good idea). – Paŭlo Ebermann Aug 15 '11 at 02:07
  • @Shawn: feel free to include parts of my explanation into your answer. – Paŭlo Ebermann Aug 15 '11 at 02:16
3

In java:

  • the == operator tests if the two objects are the same exact instance
  • the .equals() method of String compares if the objects "have the same value"

Since the user input the value, it's a new instance of String, so it will never be true that secret == input.

You should always use str1.equals(str2) when comparing Strings.

Bohemian
  • 412,405
  • 93
  • 575
  • 722