Java中new String()和intern()的那些事

今天主要是想讨论下面试中常见的String  s = new String("abc");创建了几个对象,还有String.intern()方法有什么作用。本文后面所有的结论都是基于jdk1.7及以上版本的。

1.String  s = new String("abc")创建了几个对象

答案是一个或者是两个
String s1 = new String("abc");
String s2 = new String("abc");

Java中new String()和intern()的那些事_第1张图片

这里可以看到,s1和s2中包含的value值是指向同一个地址,@474,但是s1和s2本事其实是一个String.class的对象。

所以String s1 = new String("abc");是创建了两个对象(String对象和“abc”),String s2 = new String("abc");创建了一个对象(String对象,“abc”已经存在,直接获取应用就可以)。

这里需要解释的是String对象和“abc”对象其实都是创建在堆中,而不是常量池中。只有执行String s = "abc",或者s1.intern()时,才会把堆中“abc”的引用丢入常量池。

2.intern()

上面也讲到了,intern()是把堆中的引用丢入常量池中,然后返回这个引用。当常量池中已经存在这个引用,就直接返回这个引用。接下来看几个简单的例子来理解一下:

String s1 = new String("abc");
String s2 = "abc";
System.out.println(s1.intern()==s2);//1.true
System.out.println(s1==s2);//2.false

这里,s1是String对象,s2是常量池中“abc”的引用,所以s1!=s2

然后s1.intern()是把“abc”丢入常量池中,因为常量池中已经存在“abc”的引用,所以直接返回"abc"的引用,所以s1.intern()==s2

String s1 = new String("abc") + new String("01");
s1.intern();
String s2 = "abc01";
System.out.println(s1==s2);//true

这里可以看到s1其实是两个字符串的拼接,在堆里面生成了新的字符串对象“abc01”,s1.intern()之后会把堆中的“abc01”引用丢入常量池中,s1本身就是这个引用,s2去获取“abc01”也是去常量池中获取,得到了常量池中的“abc01”引用,所以s1==s2。

String s3 = new String("abc") + new String("02");
String s4 = "abc02";
s3.intern();
System.out.println(s3==s4);//false
这里可以看到s3.intern()执行是在s4 = "abc02"之后,在s4 = "abc02"的时候,常量池中并没有“abc02”,所以创建了“abc02”并把该引用丢入了常量池中,然而s3任然是堆中“abc02”的引用,所以s3!=s4。

你可能感兴趣的:(Android基础)