浅谈String类的种种性质(二)

关于构造方法实例化String

String str = new String("hello");

实际上开辟了两个堆内存空间:

1.由于每一个字符串常量都是String'类的匿名对象,因此首先会在堆内存中开辟一块空间保存字符串"hello".

2.然后使用关键字new后,开辟了另一块堆内存空间,这块堆内存中也保存着字符串"hello".

3.栈内存str指向的实际上是new开辟的堆内存中保存的"hello".

4.而之前的那一块堆内存将因为没有栈指向称为垃圾,等待GC回收.

因此,使用new实例化String会一定程度上造成内存浪费.而且:由于关键字new开辟了新堆内存,字符串对象不会保存在对象池中而需要手工入池操作.

我们首先来看不入池下的对象比较:

 1 package testBlog;
 2 
 3 
 4 public class Test {
 5     
 6     public static void main(String[] args) {
 7         String a = new String("hello");
 8         String b = "hello";
 9         System.out.println(a==b);//结果是false
10     }
11 }

再进行手工入池操作:

 1 package testBlog;
 2 
 3 
 4 public class Test {
 5     
 6     public static void main(String[] args) {
 7         String a = new String("hello").intern();
 8         String b = "hello";
 9         System.out.println(a==b);//结果是true
10     }
11 }

将指定字符串a保存在对象池当中,这样直接赋值实例的字符串b就会自动引用已有的堆内存空间,从而a和b的内存地址相同,比较结果为true.

原文地址:https://www.cnblogs.com/ssC2H4/p/8126760.html