• Post Reply Bookmark Topic Watch Topic
  • New Topic

Object and String  RSS feed

 
ronnir paterl
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi,

I'm confused regarding the following code...

String str1 = new String("hello");
String str2 = new String("hello");

MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();

Why does
str1.equals(str2) evaluate to true
and
obj1.equals(obj2) evaluate to false?

I know that the four objects all distinct, so why are string objects treated differently? Am I missing something here?

Thanks a lot
 
Campbell Ritchie
Marshal
Posts: 55772
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I presume there was some sort of agreement made when Java was new that String objects would be treated differently.
  • String objects are immutable. Once a String is set up it cannot be changed, only replaced with a different String.
  • The compiler and JVM reuse Strings; if you write "hello" twice, they will recognise a previously-used String and reuse it.
  • So, when you write "hello" the second time, the compiler or JVM recognises that "hello" has been used once before, and reuses the same "hello". You can't change the contents of the "hello"; there is no method which allows you to change it to "goodbye".

    So, when you write "hello" again, you get a reference to the same String object you had last time.

    You should still use "equals()" to find two identical Strings, because Strings created at runtime might not be shared like that.
     
    Campbell Ritchie
    Marshal
    Posts: 55772
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I am sorry, I seem to have misunderstood your question. When you write two String literals, then both the literals are used as references to the same object.

    Have you overridden the equals() method in MyClass? If you haven't overridden it, then it will use the default implementation from java.lang.Object which reads something like this:So it only returns true if the two objects compared are references to the same object. You have to override it correctly to work in MyClass; in fact any class you plan to use in "real life" rather than an exercise ought to have an overridden equals() method, and an overridden hashCode method. See the API for java.lang.Object for more details.
     
    ronnir paterl
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    hi,

    Thanks for your help.. Initially I thought that was true too but

    str1 == str2 gives false

    Which means that both the string objects are at different locations in memory and thus the references don't match
     
    Campbell Ritchie
    Marshal
    Posts: 55772
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I would have worked that out if I had read your post properly. If you write "hello" twice you get two references to the same object, but if you write "new String("hello")" you get a reference to a different object.
     
    Bill Shirley
    Ranch Hand
    Posts: 457
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It is quite often a desirable practice that objects should implement equals() and hashcode() (if you do the first, you should do the second).

    See Object.equals()'s documentation for details.

    If you have more questions, let 'em fly.

     
    Campbell Ritchie
    Marshal
    Posts: 55772
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You ought to include a test for other != null in the equals method. If you get as far as trying to test equality against a null object, then you want to return false and exit the method PDQ before you get a NullPointerException!
     
    Ernest Friedman-Hill
    author and iconoclast
    Sheriff
    Posts: 24217
    38
    Chrome Eclipse IDE Mac OS X
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    For the poor original poster's benefit, I'm going to state explicitly that str1.equals(str2) is true because, and only because, the java.lang.String class overrides (provides its own version of) the equals() method, and that version returns true if the Strings include the same exact sequence of characters, even if they're different objects.

    There's no magic or specialness about String that's relevant here; you can override equals() in any of your classes to behave the same way. Whereas the "==" operator is always supposed to mean "is the same object", the equals() method is more usefullly used to mean "is equivalent to".
     
    Rob Spoor
    Sheriff
    Posts: 21095
    85
    Chrome Eclipse IDE Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Campbell Ritchie:
    You ought to include a test for other != null in the equals method. If you get as far as trying to test equality against a null object, then you want to return false and exit the method PDQ before you get a NullPointerException!

    Not really. getClass().isInstance(other) will return false if other is null.

    I tend to write my equals methods a bit differently:

    Now most people will use "!getClass().isInstance(o)" or something similar, but that can violate the rule that equals should be symmetric.

    Consider this example:

    Clearly this violates the rule. By checking that both classes have the exact same class this rule will not be violated.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!