public class myClass1 {
public static void main(String[] arg)
{
String str1=new String("1");//1)
String str2=new String("1");//2)
String str3="1";          //3)
         String str4="1";            //4)
               while(true)
                  {
                   }

}}
请问运行完4内存里有几个“1”
执行这几条语句时jvm都怎么分配的内存.为什么3)会自动产生一个新的“1”,而4)不会?

解决方案 »

  1.   

    JVM维护一个内部String引用列表,需要使用时首先查找该列表,如果需要的String已有,就直接引用,使用new 新建一个String对象时例外。
    所以:(1)新建一个String对象
          (2)新建一个String对象
          (3)新建一个String对象
          (4)引用已有的(3)试试这个:
    public class StringTest2 {
        public static void main(String[] arg)
        {
        String str1=new String("1");//1)
        String str2=new String("1");//2)
        String str3="1";          //3)
        String str4="1";            //4)    if(str1 == str2)
            System.out.println("str1 == str2");
        else
            System.out.println("str1 != str2");
        
        if(str3 == str1)
            System.out.println("str3 == str1");
        else
            System.out.println("str3 != str1");
        
        if(str3 == str2)
            System.out.println("str3 == str2");
        else
            System.out.println("str3 != str2");
        
        if(str3 == str4)
            System.out.println("str3 == str4");
        else
            System.out.println("str3 != str4");
        
        }
    }
    结果:
    str1 != str2
    str3 != str1
    str3 != str2
    str3 == str4
      

  2.   

    另外,可以把(2)试着改成这样:
    String str2=new String("1").intern();//2)
    强制new时先查找内部列表。
      

  3.   

    “JVM维护一个内部String引用列表,需要使用时首先查找该列表,如果需要的String已有,就直接引用,使用new 新建一个String对象时例外。”
    执行3)时String引用列表里已经有两个“1”了吧,那3)为什么不直接引用,而有产生了一个新的“1”呢?
      

  4.   

    "另外,可以把(2)试着改成这样:
    String str2=new String("1").intern();//2)
    强制new时先查找内部列表。" 在改成这种的情况下,
    我预想的是str1在应用列表中存在“1”了,
    而str2查应用列表的话就不该在产生一个“1”了
    只是返回一个引用,str1和str2应该相等(str1==str2 为true),
    而程序实际运行却不相等。
      

  5.   

    3)的确引用了上面1)2)中的"1",但是你要注意在1)中是new String("1");其实上面是先在内部建立了一个"1"字符串,然后把它作为参数传递到一个新的String对象的构造函数中。
      

  6.   

    "3)的确引用了上面1)2)中的"1",但是你要注意在1)中是new String("1");
    其实上面是先在内部建立了一个"1"字符串,然后把它作为参数传递到一个新的String对象的构造函数中。"
    能讲细一点吗?或者告诉我在哪可以找到想关的信息或关键字。
      

  7.   

    不够详细吗?只要在类中直接 "1" (包括被编译器优化过的"1" + "2" ≡ "12"),其实在类中已经包含一个内部的String成员,无论这个类后面定义了多少个"1",其实全部指向了这个内部成员但是如果你强行指定new String,JVM不会进行这样的处理,所以必定是一个新的对象