a quick and confusing question. If Class A and Class B have this inside them:-
String name="SomeName";
and both classes are instantiated, is it true that both instances refer to same memory location of variable "name" say when we do this objA.name or objB.name ? which has value "SomeName" and since String is immutable, several instances of both classes of same JVM use the same variable repeatedly? I read somewhere online that, unless there is
String example=new String("something");
is used, the former declaration always creates one copy and开发者_开发问答 it is used until all its applications are terminated for reclaiming memory. Note: I see several answers, which one do I count on, can someone conclude. Thank you all for your effort, appreciate it.
Yes, if you create two strings like:
String a = "Hello";
String b = "Hello";
They will be the exact same object. You can test it yourself by doing
System.out.println(a == b);
If they are the same object, then their internal reference to the character array will be exactly the same.
Now, if you did String c = "Hell" + "o";
, it would not have the same reference since it would have been (internally) built using StringBuilder.
There is a lot of good information here.
The relevant sections has (Note: The following is copied from that web site):
As mentioned, there are two ways to construct a string: implicit construction by assigning a String literal or explicitly creating a String object via the new operator and constructor. For example,
String s1 = "Hello"; // String literal
String s2 = "Hello"; // String literal
String s3 = s1; // same reference
String s4 = new String("Hello"); // String object
String s5 = new String("Hello"); // String object
Java has designed a special mechanism for keeping the String literals - in a so-called string common pool. If two String literals have the same contents, they will share the same storage locations inside the common pool. This approach is adopted to conserve storage for frequently-used strings. On the other hands, String object created via the new operator are kept in the heap. Each String object in the heap has its own storage just like any other object. There is no sharing of storage in heap even if two String objects have the same contents. You can use the method equals() of the String class to compare the contents of two Strings. You can use the relational equality operator '==' to compare the references (or pointers) of two objects. Study the following codes:
s1 == s1; // true, same pointer
s1 == s2; // true, s1 and s1 share storage in common pool
s1 == s3; // true, s3 is assigned same pointer as s1
s1.equals(s3); // true, same contents
s1 == s4; // false, different pointers
s1.equals(s4); // true, same contents
s4 == s5; // false, different pointers in heap
s4.equals(s5); // true, same contents
Edit to add: Run this SSCE to test reference equality between two constant strings in to different classes:
class T {
String string = "Hello";
public static void main(String args[]) {
T t = new T();
T2 t2 = new T2();
System.out.println(t.string == t2.string);
}
}
class T2 {
String string = "Hello";
}
prints out true
.
If "something" is literally hard-coded into your source code, then the two variables will point to the same in-memory String object.
Per the Java spec, a string literal (one that's defined as a literal in the byte codes) is "interned", so that any reference to that literal will obtain the exact same pointer, even if the reference is to an identical literal in an entirely separate class.
A string constructed at runtime (eg, "abc" + "xyz" or new String("abc")) will not be interned, and so the pointer will generally be unique. (But note that an optimizing compiler may combine "abc" + "xyz" into the single literal "abcxyz", resulting in an interned value.)
the former declaration always creates one copy and it is used until all its applications are terminated for reclaiming memory.
Strings, like other object are reclaimed when a GC is performed and there is no strong reference to it. Even intern'ed Strings can be cleaned up when they are no longer used.
I would add one more detail to all the solutions above. String interning is just an optimization of Java/C# compiler. It's not good to rely on it as it can be turned off in both cases.
It may also behave differently in different compilers/VM's implementations
精彩评论