Bizarre problem with Strings obtained from readLine

Hi,

when I run the code below, the if statement simply DOES NOT work, even though I successfully print out the variable before evaluating it.

However, if I statically set the value of 'answer', it's fine.

What is going on?

import java.io.*;

publicclass SimpleMath

{

publicstaticvoid main(String[] args)throws IOException

{

BufferedReader in =new BufferedReader(new InputStreamReader(System.in));

String answer;

answer = in.readLine();

System.out.println("You said:" + answer);//this works fine!

if (answer =="y")

{

System.out.println("Oi! it worked!");//this never runs!

}

}

}

[1332 byte] By [henkk78a] at [2007-11-26 22:47:11]
# 1

>

>

>if (answer == "y")

> {

> System.out.println("Oi! it worked!"); //this never runs!

>}

>

Read Section 15.21.3 of the Java language specification.

Niceguy1a at 2007-7-10 12:05:59 > top of Java-index,Java Essentials,Java Programming...
# 2

Okay, Niceguy, I assume you're referring to the below, which makes absolutely not sense to me really...

Why DOES the code work if i said:

answer = "y";

if (answer == "y") System.out.println("Oi, it works!");

but NOT when I say:

answer = in.readLine();

if (answer == "y") System.out.println("Oi, it works!");

Doesn't 'answer' hold exactly the same value? (in the case that I typed 'y' at the prompt)

I (vaguely) understand the what they mean by saying i'm comparing a String Object with a string of characters ("y'), but it still seems inconsistent, in the case that the first piece of code actually works.

15.21.3 Reference Equality Operators == and !=

If the operands of an equality operator are both of either reference type or the null type, then the operation is object equality.

A compile-time error occurs if it is impossible to convert the type of either operand to the type of the other by a casting conversion (?.5). The run-time values of the two operands would necessarily be unequal.

At run time, the result of == is true if the operand values are both null or both refer to the same object or array; otherwise, the result is false.

The result of != is false if the operand values are both null or both refer to the same object or array; otherwise, the result is true.

While == may be used to compare references of type String, such an equality test determines whether or not the two operands refer to the same String object. The result is false if the operands are distinct String objects, even if they contain the same sequence of characters. The contents of two strings s and t can be tested for equality by the method invocation s.equals(t). See also ?.10.5.

henkk78a at 2007-7-10 12:05:59 > top of Java-index,Java Essentials,Java Programming...
# 3

Hey man:

this is your code right:

import java.io.*;

public class SimpleMath

{

public static void main(String[] args) throws IOException

{

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

String answer;

answer = in.readLine();

System.out.println("You said:" + answer); //this works fine!

if (answer == "y")

{

System.out.println("Oi! it worked!"); //this never runs!

}

}

}

what you are doing actually is creating another string object in the memory contains y and compare references, so the right way to do the if statement is:

if (answer.equals("y"))

{

System.out.println("Oi! it worked!"); //this never runs!

}

and also check if the text returned from the file doesn't contain spaces after the word.

hope this helps.

invokeLatera at 2007-7-10 12:05:59 > top of Java-index,Java Essentials,Java Programming...
# 4

> ...

>

> Doesn't 'answer' hold exactly the same value? (in the

> case that I typed 'y' at the prompt)

>

> ...

No, their contents is the same, but, in case of the nextLine(), not their references (values).

Run this demo:public class Main {

public static void main(String[] args) {

StringBuffer buffer = new StringBuffer();

buffer.append('y');

String s1 = "y";

String s2 = buffer.toString(); // this is what happens in the class you call nextLine() on

String s3 = "y"; // "y" already exists in the String pool, so the reference of s1 gets recycled. hence s1==s3

String s4 = new String("y"); // a new "y" is constructed (next to the existing one)

System.out.println("s1 == s2-> "+s1+" == "+s2+"? "+(s1 == s2));

System.out.println("s1.equals(s2) -> "+s1+".equals("+s2+") ? "+s1.equals(s2));

System.out.println("s1 == s3-> "+s1+" == "+s3+"? "+(s1 == s3));

System.out.println("s1 == s4-> "+s1+" == "+s4+"? "+(s1 == s4));

}

}

/*

output:

s1 == s2-> y == y? false

s1.equals(s2) -> y.equals(y) ? true

s1 == s3-> y == y? true

s1 == s4-> y == y? false

*/

prometheuzza at 2007-7-10 12:05:59 > top of Java-index,Java Essentials,Java Programming...
# 5

> Okay, Niceguy, I assume you're referring to the

> below, which makes absolutely not sense to me

> really...

>

> Why DOES the code work if i said:

>

> > answer = "y";

> if (answer == "y") System.out.println("Oi, it

> works!");

>

Because the compiler 'interns' the String literals. See Section 3.10.5.

>

> but NOT when I say:

>

> > answer = in.readLine();

> if (answer == "y") System.out.println("Oi, it

> works!");

>

Here 'answer' isn't a String literal, so no interning takes place.

Jim S.

Niceguy1a at 2007-7-10 12:06:00 > top of Java-index,Java Essentials,Java Programming...