用中文来说literal是不是就是“常量”?
我想问的是一个String literal 和new String() 出来的有什么区别?
比如:
//----------1-----------------------
String s1 = "Cme";
String s2 = "Cme";
if(s1.equals(s2)){
    System.out.println("true");
}
//----------------------------------//----------2-----------------------
String s1 = "Cme";
String s2 = "Cme";
if(s1==s2){
    System.out.println("true");
}
//----------------------------------
两段程序都打印出“true”。第一段没问题,比较对象的内容,s1和s2相等
第2段,s1 和s2 都是用字符串常量赋的值。书上是这么说的:Every string literal is represented internally by an instance of String.Java classes may have a pool of such strings. When a literal is compiled,the compiler adds an appropriate string to the pool.However,if the same literal already appeared as a literal elsewhere in the classes,then it is already represented in the pool.The compile does not create a new copy.Instead,it uses the existing one from the pool.This process saves on memory and can do no harm.照这样说第2段程序的输出也没问题,我想问的是他所说的“Java classes may have a pool of such strings,When a literal is compiled,the compiler adds an appropriate string to the pool”
这里的pool是指的哪的存储空间?每个类都有这样一个空间?怎么来理解?

解决方案 »

  1.   

    应该是创建到栈内存中,因为String 是一个比较特殊的对象。
    其中有一个String的优化比如说  String str1="abc";
            String str2="abc";用== 和equals()方法比较都是true
      

  2.   

    在书上找到了答案,不知道我理解的对不对:
    1. String s1 = "immutable";的创建过程
        用字符串常量创建String型的对象时,在编译时,编译器向字符串常量缓冲区中添加该常量,
    如果还有String s2 = "immutable";编译器会先判断缓冲区中是否有此常量,有的话就不会创建新的,而直接使用已有的字符串常量。这样s1 和 s2 就指向了同一个地址,两者的内容也都相同,即用== 和equals()方法比较都是true2. String s2 = new String("Constructed");的创建过程
        当这行代码被编译时,字符串常量"Constructed"先被放进缓冲区中,到了运行时,new String()语句被执行,一个新的String实例被创建,并复制缓冲区中的字符串到新分配的内存空间中。最后新建的String对象被赋予s2,
    显然,用new String()语句将导致额外的内存分配。
      

  3.   

    literal 是只有一份,共享的, 因为 String 是个不可变量,所以说是  "can do no harm" ,
    String.intern() 就是用来查找一份现存的 literal 拷贝(得到它你可以释放其他拷贝, 
    String str1 = new String("ONE");
    String str2 = new String("ONE");
    String str3 = new String("ONE");str1.intern() == str2.intern() == str3 .intern()  成立。我们可以这样保持更少的拷贝。
      

  4.   

    String s1 = "Cme";
    String s2 = "Cme";
    应该是编译器做的优化,通过无环有向图(DAG),上面的语句实际上就变成了 s1=s2="Cme"。所以s1,s2引用的地址也是相同的。如果s2的值是通过另一个类的方法返回的,if就为假了。
      

  5.   

    String s1 ="yy"会被编译成String s1 = new String("yy")。
    所以二者是一样的。
      

  6.   

    这里的pool是指的哪的存储空间?每个类都有这样一个空间?怎么来理解?
    -----------------------------------------------------------------<Effective Java>上有一段话回答了这个问题:String s = "No longer silly";This version uses a single String instance, ranther than creating a new one each time it is executed. Furthermore, it is guaranteed that the object will be reused by any other code running in the same virtual machine that happens to contain the same string literal.也就是说, 同一个String literal在一个虚拟机中只存在一份, 所有运行在同一个虚拟机中的程序都共享这个常量池.