String什么时候创建一个新对象?

 1                 String a="a";
 2         String b="b";
 3         String c="a"+"b";
 4         String d=a+b;
 5         String e="ab";
 6         String f=new String("ab");
 7         System.out.println(c==d);          //false
 8         System.out.println(c==e);            //true
 9         System.out.println(e==f);            //false
10         System.out.println(e==f.intern());    //true
11         }
View Code

      第3个false显而易见,使用new关键字就会分配一块新的内存,所以比较地址肯定是false

   第1个false其实和第3个false原因是一样的,对于d让两个String对象相加就会自动的使用new关键字调构造方法

   第2个为true,是因为编译的时候,会自动优化中间的那个+号,让c=“ab”,此时这个"ab"字符串在方法区的常量池是没有的,那么会将这个“ab”字符串放入常量池并返回常量池中这个“ab”字符串的引用地址,所以c指向的是常量池中的那个“ab”,而e在赋值“ab”时就会检测到常量池中已经有了这么一个字符串,所以e也指向的是常量池中的“ab”,所以c和e指向的是常量池中的同一个字符串,所以c和e相等,第2个输出结果为true。

  第4个为true,f.intern()会返回常量池中和f这个字符串字符相同的字符串的引用,所以返回的引用地址就是常量池中的“ab”的地址,而e指向的就是常量池中的“ab”,所以第4个结果为true。

 

总结:

  生成一个字符串首先判断字符串常量池是否有这么一个字符串,没有则会在常量池放入该字符串,再进行接下来的操作。

  对于new String("ab")这样的一个操作会生成的对象个数可能是1,也可能是2,如果常量池中有“ab”字符串,那么就直接在堆分配一块内存,此时创建了一个对象存放“ab”,否则,首先在方法区的字符串常量池分配内存存放“ab”,然后在堆分配一块内存,存放“ab”,此时创建了两个对象。

  对于String a="ab"这样的一个操作,生成的对象个数可能是0,也可能是1,原因同上。

猜你喜欢

转载自www.cnblogs.com/darkclouds/p/11695166.html