//希望对你有用
There is difference between the two types of instantiations of the String object. The instantiation String s1 = "abc"; //literal String allocates the String object from the String Pool of the JVM. The JVM creates a String Pool at startup. Java requires that identical string literals (that is, literals that contain the same sequence of Unicode characters) must reference the same instance of class String. So, if you have another String object String s2 = "abc", then both s1 and s2 point to the same memory location. Thus in this case s1 == s2 and s1.equals(s2) both will return true. But if you declare s1 and s2 as String s1 = new String("abc"); 
and s2 = "abc" or viceversa or both instantiated with new, s1 == 
s2 will return false as they point to different memory locations, one in the constant Pool and one on the Heap. But s1.equals(s2) will return true. If you have further questions about this, read section 5.4 at http://java.sun.com/docs/books/vmspec/html/ConstantPool.doc.html Hope this helps!!! 

解决方案 »

  1.   

    //这是我找的资料,我想比原来的说的更清楚。
    //希望能有用。The "String" class maintains a pool of strings internally for your java program. 
    So, your next question will be "what is the content of this pool?". Whenever, you initialize an object of class "String" with a constant expression then the value of that constant expression ( of course, it will be a String ) is stored in the "String" pool and in Java jargon we say that the string has been interned. Let us take an example. 
    String str1 = "hello" ; 
    String str2 = "hi" ; 
    String str3 = "hello" + " hi" ; 
    Now you can see all the three String objects str1, str2 and str3 have been initialized with a constant expression and so the global ( but private ) pool maintained by class String has three entries viz. "hello", "hi" and "hello hi" . Now you may initialize a fouth String object like 
    String str4 = "hello" + str2 ; 
    This time the variable str4 has been assigned a value "hellohi", but this string "hellohi" is not stored in the pool of String class. Do you know why? 
    Because, the expression "hello" + str2 is not a constant expression. str2 is a variable. 
    I think you are clear about the "how part" of automatic intering of a string in java. 
    Let us move to another question "why part" - "Why String class interns all the stings resulting from a constant expression?". Write one more line of code as follows. 
    String str5 = "hello" ; 
    You know str1 and str5 are two different objects of class String. What is common with them. Of course, the content which is "hello". No. We are partially right in saying str1 and str5 have only one thing in common and that is their content "hello". They are exactly representing the exactly same object in memory. But, how all these rubbish happened? Here comes the importance of automatic interning the strings. Whenever, you wrote a code like 
    String temp = "hello" ; 
    first of all java looks for the string "hello" in the internal string pool of class String. If it has already interned a String "hello" then it just returns the reference to that string "hello" 
    in pool to the variable "temp", otherwise it interns 
    the string and then returns the reference. Since in our case before we wrote 
    String str5 = "hello" ; 
    the string "hello" was already interned by statement 
    String str1 = "hello" ; 
    So now both str1, str5 and temp are pointing to the same string object in string pool whose content is "hello". But, how to prove it? 
    You know the == operator 
    in java compares the references of two objects. Now you can prove it like if ( str1 == str5 ) { 
    System.out.println ( "i din't lie about string intering" ) ; 

    else { 
    System.out.println ( "i lied about string intering" ) ; 
    } This way java utilizes the memory efficiently by 
    interning the strings. However, if you create a string object using new operator then irrespective of the string content java always allocates new memory for each object. 
    String s1 = new ( "hello" ) ; 
    String s2 = new ( "hello" ) ; 
    Try s1 == s2 and it will return false because event if string contents are same for s1 and s2 they have different references in memory. So in case of intering of strins 
    s1 == s2 a well as s1.equals ( s2 ) returns true where as in using new operator 
    s1 == s2 will never return true but s1.equals ( s2 ) may return true if and only if the contents of two strings are same. Whenever possible it is preferable to use a String literal rather than the 'new' keyword to create a new instance of a String object. Because String literals are unique to each class, only one copy of each unique String literal exists per class. The cumulative effect of this can represent a significant saving of memory. For example: class Test{ 
    public static void main(String[] args) { 
    String s1 = "Hello"; 
    String s2 = "Hello"; 
    String s3 = new String("World"); 
    String s4 = new String("World"); boolean b1 = (s1 == s2); 
    boolean b2 = (s3 == s4); 
    boolean b3 = s1.equals(s2); 
    boolean b4 = s3.equals(s4); System.out.println("b1 is " + b1); 
    System.out.println("b2 is " + b2); 
    System.out.println("b3 is " + b3); 
    System.out.println("b4 is " + b4); 

    } In the above example the String s1 and s2 point to the same String object, but s3 and s4 point to different String objects. As a result, the comparison(s1 == s2) is true while (s3 == s4) is false. Note that both s1.equals(s2) and s3.equals(s4) are true. Also when the 'new' keyword is used to create a new instance of a String object, that object is placed on the Heap, and Heap-based strings are less efficient than String literals which are placed in the runtime constant pool. The Strings on the heap are transient, so they won't take up RAM all the time. However, since they are transient they need to be reallocated and then collected each time you go through a piece of code which calls "new String". This causes the garbage collector to have to work a lot harder and can slow down your performance. 
      

  2.   

    呵呵,我试着解释一下,不一定对噢。你看你的语句:
         myStr1=myStr2;
    这样的话,你只是把mystr2的句柄给了mystr1,它们已指向同一块内存,此时,mystr1所分配的内存已经进了回收站,
    如果不想同步改变的话,你必须实现类的拷贝。通常是在构造函数中实现。