Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 05-03-2004, 01:37 PM   #1 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,530
sde is on a distinguished road
== 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
sde is offline   Reply With Quote
Old 05-03-2004, 06:19 PM   #2 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
Because == compares the *pointers* of objects (and values of primitives). Primitives are unique according to value, objects are unique according to memory address.
__________________
GitS
Belisarius is offline   Reply With Quote
Old 05-03-2004, 06:34 PM   #3 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
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".
__________________
GitS
Belisarius is offline   Reply With Quote
Old 05-03-2004, 06:49 PM   #4 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
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.
__________________
GitS
Belisarius is offline   Reply With Quote
Old 05-03-2004, 06:51 PM   #5 (permalink)
joe_bruin
LOAD "*",8,1
 
Join Date: Feb 2003
Location: la.ca.us
Posts: 254
joe_bruin is on a distinguished road
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.
joe_bruin is offline   Reply With Quote
Old 05-03-2004, 06:55 PM   #6 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,530
sde is on a distinguished road
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
sde is offline   Reply With Quote
Old 05-03-2004, 06:56 PM   #7 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
Code:
public class test{
  public static void main(String args[]){
    String a = "Foo";
    String b = a;

    System.out.println(a==b);
  }
}
__________________
GitS
Belisarius is offline   Reply With Quote
Old 05-03-2004, 07:05 PM   #8 (permalink)
joe_bruin
LOAD "*",8,1
 
Join Date: Feb 2003
Location: la.ca.us
Posts: 254
joe_bruin is on a distinguished road
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.
joe_bruin is offline   Reply With Quote
Old 05-03-2004, 07:10 PM   #9 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
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".
__________________
GitS
Belisarius is offline   Reply With Quote
Old 05-03-2004, 10:43 PM   #10 (permalink)
joe_bruin
LOAD "*",8,1
 
Join Date: Feb 2003
Location: la.ca.us
Posts: 254
joe_bruin is on a distinguished road
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.
joe_bruin is offline   Reply With Quote
Old 05-04-2004, 03:57 AM   #11 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
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.
__________________
GitS
Belisarius is offline   Reply With Quote
Old 05-04-2004, 03:23 PM   #12 (permalink)
joe_bruin
LOAD "*",8,1
 
Join Date: Feb 2003
Location: la.ca.us
Posts: 254
joe_bruin is on a distinguished road
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.
Code:
String s = "foo";
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.
joe_bruin is offline   Reply With Quote
Old 05-04-2004, 04:48 PM   #13 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
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.
__________________
GitS
Belisarius is offline   Reply With Quote
Old 05-04-2004, 05:07 PM   #14 (permalink)
joe_bruin
LOAD "*",8,1
 
Join Date: Feb 2003
Location: la.ca.us
Posts: 254
joe_bruin is on a distinguished road
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.
joe_bruin is offline   Reply With Quote
Old 05-04-2004, 05:11 PM   #15 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,175
Belisarius is on a distinguished road
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?
__________________
GitS
Belisarius is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -8. The time now is 12:45 AM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0 RC8 ©2007, Crawlability, Inc.





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting