下列哪些生成新的string对象()
A. String s= new String();
B. String s = new String("A");
C. String s="";
D. String s = "A".intern();
E. String s = (String)String. class . newInstance();
答案:A,B,C,D,E
知识点:
Java String 最常见的两种创建方式:
1.常量式创建:String str = "abc";
JVM为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化:使用字符串常量池。
每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串。“
换句话说如果字符串常量池中存在“abc”,则直接指向它,否则就在字符串常量池中创建“abc”,并返回引用地址。
2.对象式创建:String str2 = new String("abc");
这种创建形式跟我们一般创建对象的形式一样,创建完的对象存在堆中,str2变量存在栈中对应内容是指向创建好的string对象的引用地址。string对象在创建时会先在字符常量池中去查看是否存在“abc”,若不存在,则在字符常量池中创建“abc”字符串对象,并将引用地址传给堆中的字符串对象;如果字符串常量池中存在“abc”,则直接将引用地址传给堆中的字符串对象。
3.其它创建对象方式:
和一般创建对象的形式一样如反射,克隆,反序列化。
关于String面试题扩展
以下题目都不考虑字符串常量池中提前有该字符串对象
1.String str = new String("abcd");实例化了几个字符串对象?
答案:两个。一个在堆中,一个在字符串常量池。
解释:变量str在栈中,存放了引用在堆中创建的字符串对象的地址,在堆中创建的字符串对象在创建时先去字符串常量池中查看是否有“abcd”字符串对象,因本题默认字符常量池中不存在该字符串对象,所以会先在字符串常量池中创建一个“abcd”的字符串对象,将该地址返回给堆中创建的字符串对象,即堆中的字符串对象引用字符串常量池的“abcd”字符串对象。
验证:
2.String str = "a" + "b";产生几个字符串对象?
答案:1个。在字符串常量池中。
解析:JVM看到两个或多个字面量直接相加的时候会对其进行优化直接生成一个字符串到常量池中。
验证:
3.String str = "a" + new String("b");产生几个字符串对象?
答案:一共创建四个字符串对象,常量池中有两个(分别是a和b),堆中有两个(分别是a和StringBuilder)
验证:
4.String str1 = new String("abc");String str2 = new String("abc");一共创建了几个字符串对象?
答案:3个。常量池中一个,堆中两个。
验证:
5.String str = new String("a") + new String("b");创建了几个字符串对象?
答案:5个。堆中有3个,常量池中2个。
解析:为什么不是六个呢?ab跑哪去了?
使用引号包含文本的创建String对象之间使用”+“连接,产生的对象会被加入到String常量池中,对于所有包含new方式创建的字符串对象的”+“连接表达式,它所产生的新对象不会加入到常量池中。
验证: