English 中文(简体)
Basic Java question: String equality
原标题:
public class A {

    static String s1 = "I am A";

    public static void main(String[] args) {
        String s2 = "I am A";
        System.out.println(s1 == s2);
    }
}

Above program outputs "true". Both are two different identifiers/objects how the output is "true" ?

My understanding is that the JVM will create different reference for each object, if so how the output is true?

最佳回答

Java manages a String literal pool. It reuses these literals when it can. Therefore the two objects are actually the same String object and == returns true.

I believe this is called string interning

问题回答

== checks that the variables are pointing at the exact same instance of an object. The two string literals you have created point to the same place in memory and therefore the are equal. String literals are interned so that the same string literal is the same object in memory.

If you were to do

String s = new String("foo");
String t = new String("foo");

Then == would return false and s.equals(t) would return true.

It s because of a memory optimization performed by the compiler... namely, String constants (ie - Strings made by the same String literal) use the same String object since Strings are immutable. The == operator just checks that two objects are the same actual object.

If you can grab a hold of the book Java Puzzlers by Joshua Bloch and Neal Gafter, and look at puzzle 13, "Animal Farm"... he has great advice on this issue. I am going to copy some relevant text:

"You may be aware that compile-time constants of type String are interned [JLS 15.28]. In other words any two constant expressions of type String that designate the same character sequence are represented by identical object references... Your code should rarely, if ever, depend on the interning of string constants. Interning was designed solely to reduce the memory footprint of the virtual machine, not as a tool for programmers... When comparing object references, you should use the equals method in preference to the == operator unless you need to compare object identity rather than value."

That s from the above reference I mentioned... pages 30 - 31 in my book.

Because the Java Language Specification says:

String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are "interned" so as to share unique instances, using the method String.intern.

You aren t comparing the content of the strings. You are only comparing the object s references. You should use the equal method (which is a member of the String class). Either that or you can use the compareTo method (also under the same String class) to check if the return value is zero.

Please note the text above was more of a strong suggestion to the orginal state of the question as that it appeared the OP was unaware of the actual process going on behind the scenes.

The other guys suggesting internalling was right. To answer this question I didn t have enough time to go to the Java Puzzlers book. I did suspect something about setting the same reference at compile time, but I didn t know how to find a reference to that either.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签