|  | |  |
05-03-2004, 01:37 PM
|
#1 (permalink)
| | Moderator
Join Date: May 2002 Location: us.ca
Posts: 4,530
| == vs .equals() what the heck?
why can't i use == to test for equality between strings with java?
example: Code: String myState="CA";
String states = new String[] { "CA","AZ" };
if( states[0]==myState )
{
// this will always fail
}
if( states[0].equals(myState) )
{
// this is true
}
i this was mentioned before, but i want to now precisely why.. or is there no good answer?
__________________ Mike |
| |
05-03-2004, 06:19 PM
|
#2 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| Because == compares the *pointers* of objects (and values of primitives). Primitives are unique according to value, objects are unique according to memory address. |
| |
05-03-2004, 06:34 PM
|
#3 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| Oh, and "states[0]==myState" won't actually always fail. I messed around with it and was able to get it to return true. It's due to optimizations within the compiler.
Basically, the only time you use "==" with Objects is to test for "null". |
| |
05-03-2004, 06:49 PM
|
#4 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| If you want a more philosophical reason for it, I can ask my professor about it. The answer would probably be like an essay, as when they were developing Java, a *lot* of thought went into it. It's not like Perl or PHP which grew up as convience languages. Java was designed from a strong understanding of software engineering and best practices, as well as learning from the mistakes of C and C++.
I'm not sure of the procedure for development of Perl or PHP, but Java incorporates technology/language improvements approved by committee in the Java Community Process ( www.jcp.org). Changes come slowly, and only after much deliberation. I know my professor (who happens to be on the executive committee for JCP) found a bug in the 1.5 beta that occurred only after 6 hours of stress-testing on a dual-athlon Linux system. Took him months to chalk it up to a bug in the kernel. |
| |
05-03-2004, 06:51 PM
|
#5 (permalink)
| | LOAD "*",8,1
Join Date: Feb 2003 Location: la.ca.us
Posts: 254
| Quote: Originally posted by Belisarius Basically, the only time you use "==" with Objects is to test for "null". | or if you wanted to know whether two objects are actually the same object or not (not two objects that are equal, actually the same instance). Quote: |
Oh, and "states[0]==myState" won't actually always fail. I messed around with it and was able to get it to return true. It's due to optimizations within the compiler.
| yes, it would work if states[0] points to the same memory location as myState, both are null, or possibly if one or more of them is uninitialized. i'd love to see a case where they're both initialized properly, are different, and it still evaluates to true. |
| |
05-03-2004, 06:55 PM
|
#6 (permalink)
| | Moderator
Join Date: May 2002 Location: us.ca
Posts: 4,530
| ok, thanks a lot guys. i guess i didn't realize == in java tests for the same identical object. ( sometimes or whatever ) lol
thanks
__________________ Mike |
| |
05-03-2004, 06:56 PM
|
#7 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| Code: public class test{
public static void main(String args[]){
String a = "Foo";
String b = a;
System.out.println(a==b);
}
} |
| |
05-03-2004, 07:05 PM
|
#8 (permalink)
| | LOAD "*",8,1
Join Date: Feb 2003 Location: la.ca.us
Posts: 254
| PHP Code: $ java test
true
hmm, that's the expected result, since a and b point to the same object. Quote: |
i'd love to see a case where they're both initialized properly, are different, and it still evaluates to true.
| |
| |
05-03-2004, 07:10 PM
|
#9 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| You'd think so. But if you tack on: Code: a = "bar";
System.out.println(b); If they were the same object, "b" would continue to have the same value as "a". |
| |
05-03-2004, 10:43 PM
|
#10 (permalink)
| | LOAD "*",8,1
Join Date: Feb 2003 Location: la.ca.us
Posts: 254
| Quote: Originally posted by Belisarius If they were the same object, "b" would continue to have the same value as "a". | absolutely not. you're confusing the object with the reference to the object.
let's say "Foo" is object #1, and "bar" is object #2. here is the state of your references throughout the code: Code: public class test{
public static void main(String args[]){
String a = "Foo"; // now a is a reference to #1
String b = a; // b is also a reference to #1
System.out.println(a==b); // #1 == #1 (true)
a = "bar"; // a is now a reference to #2. b is unchanged (#1)
System.out.println(b); // println(#1)
System.out.println(a==b); // #2 == #1 (false)
}
} now, if we were changing the object directly (instead of the reference), you'd be correct. Code: Integer a = new Integer(5);
Integer b = a;
System.out.println(a==b); // true
a.setValue(9);
System.out.println(b); // will print 9
System.out.println(a==b); // still true
// neither a nor b changed, only the object they both point to. |
| |
05-04-2004, 03:57 AM
|
#11 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| I'll concede the point. But there's another example I think is an example of optimizations producing an unexpected result. Code: String a = "foo";
String b = "foo";
char data[] = {'f','o','o'};
String c = new String(data);
System.out.println(a==b);
System.out.println(a==c); Now, a and b are initialized independantly of each other. In the API documentation for String, it says that setting a string using "foo" or an array of chars is equivilant. But, as you can see, "foo" is treated like an object reference, as opposed to an independant constructor. That's why a == b is equal, but a == c isn't. |
| |
05-04-2004, 03:23 PM
|
#12 (permalink)
| | LOAD "*",8,1
Join Date: Feb 2003 Location: la.ca.us
Posts: 254
| ah, i understand the confusion, although the results are entirely expected. this has to do with the weird way that java treats strings. you will not be able to replicate this using any other class.
String is the only class where you can "assign" a value to. java is actually faking this assignment. this is a major breach in the standard java way of dealing with objects, but it was done to make String act more like a primitive type. what really happens is that the compiler turns the above assignment into this: Code: static final String f = new String("foo");
String s = f; now here is how this applies in your program. your above program transforms into the following: Code: public class test{
public static final String f = new String("foo");
public static void main(String args[]){
String a = f;
String b = f;
char data[] = {'f','o','o'};
String c = new String(data);
System.out.println(a==b);
System.out.println(a==c);
}
} notice that a and b both point to f. any good programmer would have done the same since f is final (and all java Strings are final anyway). c is different, because it is explicitly allocated by you from dynamic data.
therefore, (a == b) is true, but (a == c) is false. |
| |
05-04-2004, 04:48 PM
|
#13 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| Yes, this part I understand. However, guess when a new Java coder will most likely use "=="? String comparison. It's a pitfall. It will work in their test program, but when they try to apply it to a real program, bad things happen. Hence the pounding of "equals()" for objects, "==" for primitives, and my warning that "==" doesn't always do what you think it will. |
| |
05-04-2004, 05:07 PM
|
#14 (permalink)
| | LOAD "*",8,1
Join Date: Feb 2003 Location: la.ca.us
Posts: 254
| i agree with you completely, always use equals() to check for equality of objects.
what i was taking issue with is that you implied that "==" sometimes does not work as expected (due to compiler optimizations). i say "==" always works correctly and consistanly, it's just that most people's expectations of how it should work are wrong. |
| |
05-04-2004, 05:11 PM
|
#15 (permalink)
| | Java fanboy
Join Date: Aug 2003
Posts: 1,175
| Now we're getting into semantics 
Yes, it works the way it's documented, but as an exception to the general rule. How many people actually read the Java Language Def? |
| | | Thread Tools | | | | Display Modes | Linear Mode |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | All times are GMT -8. The time now is 12:45 AM. |
Copyright © 2000-2008, Milano Interactive Web Hosting provided by Portal 360 Web Hosting |  | |