1.String对象具有只读性,对他的任何引用都不能改变他的值,例如:String s=”abc”+”def”+”mango”+”47″;

其工作原理是1.abc先与def结合形成新的对象A,对象A又于mango结合生成新的对象B,对象B由于47结合生成新的对象C,在生成最终的对象时会产生一堆垃圾对象,

  1. public class test { 
  2.   public static void main(String[] args) { 
  3.       String a = “abc”
  4.       String b = “abc”
  5.       System.out.println(a == b);  // true 
  6.       String c = new String(“abc”); 
  7.       System.out.println(a == c);  // false 
  8.       System.out.println(a.equals()); // true   
  9.   } 

上面这段代码在执行完String a = “abc”这一句的时候会在内存中创建一个值为abc的String类型对象。当执行下一句代码,即String b = “abc”的时候,java会首先去驻留池里面查找是否有值为abc的字符串对象,如果有就让b引用执行那个对象,如果没有就新创建一个并且将其存放在驻留池中。所以,不难理解,当程序执行到第三句话的时候会返回true,我们知道==在java中比较的是对象的引用指向的对象的内存首地址是否一样,而a和b指向的是同一个对象,所以会返回true。继续往下走,当程序执行到String c = new String(“abc”)这句话的时候,java做的事包括: 检查abc这个字符串对象是否在驻留池中,如果存在就把它当做值,然后再在堆上创建一个String类型的对象放到堆中(我们都知道在java中对象是放在堆中,对象的引用是存放在栈中)。所以这句话其实可能创建了2个对象(如果abc已经在驻留池中了,就只是在堆中创建了一个对象)。同时通过new String()创建出来的字符串对象是不会被放到驻留池中的。你也许会想,有没有一种方法让我把在堆中创建的对象放到驻留池中去呢?答案是有的!java提供了一个方法叫做intern(),如果执行c.intern(),会首先把c指向的对象放到驻留池中,然后返回指向这个对象的引用。那么,以下代码会输出什么呢?

使用+连接字符串每次都生成新的对象,而且是在堆内存上进行,而堆内存速度比较慢(相对而言),那么再大量连接字符串时直接+是不可取的,当然需要一种效率高的方法。Java提供的StringBuffer和StringBuilder就是解决这个问题的。区别是前者是线程安全的而后者是非线程安全的。此外,值得注意的一点是,驻留池是不会被GC回收的,它会在程序运行期间一直保留。

2.


版权声明:本文为xinjingsihai原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xinjingsihai/article/details/51755277