Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How "==" works for objects?

Tags:

java

public static void main(String [] a)
{
    String s = new String("Hai");
    String s1=s;
    String s2="Hai";
    String s3="Hai";
    System.out.println(s.hashCode());
    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    System.out.println(s3.hashCode());
    System.out.println(s==s2);
    System.out.println(s2==s3);

}

From the above code can anyone explain what is going behind when JVM encounters this line (s==s2) ?

like image 770
Hariharbalaji Avatar asked Dec 11 '09 12:12

Hariharbalaji


1 Answers

It compares references - i.e. are both variables referring to the exact same object (rather than just equal ones).

  • s and s2 refer to different objects, so the expression evaluates to false.
  • s and s1 refer to the same objects (as each other) because of the assignment.
  • s2 and s3 refer to the same objects (as each other) because of string interning.

If that doesn't help much, please ask for more details on a particular bit. Objects and references can be confusing to start with.

Note that only string literals are interned by default... so even though s and s2 refer to equal strings, they're still two separate objects. Similarly if you write:

String x = new String("foo");
String y = new String("foo");

then x == y will evaluate to false. You can force interning, which in this case would actually return the interned literal:

String x = new String("foo");
String y = new String("foo");
String z = "foo";

// Expressions and their values:
x == y: false
x == z: false
x.intern() == y.intern(): true
x.intern() == z: true

EDIT: A comment suggested that new String(String) is basically pointless. This isn't the case, in fact.

A String refers to a char[], with an offset and a length. If you take a substring, it will create a new String referring to the same char[], just with a different offset and length. If you need to keep a small substring of a long string for a long time, but the long string itself isn't needed, then it's useful to use the new String(String) constructor to create a copy of just the piece you need, allowing the larger char[] to be garbage collected.

An example of this is reading a dictionary file - lots of short words, one per line. If you use BufferedReader.readLine(), the allocated char array will be at least 80 chars (in the standard JDK, anyway). That means that even a short word like "and" takes a char array of 160 bytes + overheads... you can run out of space pretty quickly that way. Using new String(reader.readLine()) can save the day.

like image 70
Jon Skeet Avatar answered Sep 28 '22 08:09

Jon Skeet