public static void main(String[ ] args) {
String s = new String("aaa");
}
该语句创建了几个String对象?
我想这是一个经常出现在面试题中的问题。我们先不回答它,比较比较它们的引用先。
public static void main(String[ ] args) {
String s = new String("aaa");
System.out.println(s == "aaa");
}
打印的是false。
那么可以推断出创建了两个对象(两个不同对象在堆中地址肯定不同)
解释下:
对于字符串"aaa",JVM首先检查在字符串池中是否已经存入。如果没有,则新建一个(new)。
这里由于之前没有创建过aaa,因此字符串池肯定没有,所以先创建一个字符串对象"aaa",然后放入字符串池中。
继续
接下来遇到new关键字,那么肯定会创建一个字符串和"aaa"一样的字符串,只不过是在堆中另外开辟一段空间。
因此,该语句一共创建了两个字符串对象,它们值一样,但是地址不一样。
所以用==比返回false,用equals返回true。
上面语句等价于:
public static void main(String[ ] args) {
// String s = new String("aaa");
// System.out.println(s == "aaa");
String s = "aaa"; // check if exists in pool of string.If not,new one and put it into pool
s = new String(s); //whatever it is in or not in the pool,new one with given value.
}
其它测试例子:
public static void main(String args[]) {
/* 全部是字符串 */
String a = "abc";
String b = "abc" + "def";
String c = "abc" + "def" + "mno";
/* 含有boolean */
String d = true + "abc";
/* 含有整数(byte,short,int,long) */
String e = 5 + "abc";
/* 含有double(float) */
String f = "abc" + 5.5;
/* 含有 char */
String g = "asdf" + 'g';
/* 含有变量 */
String h = f + "abc";
String i = f + g;
String j = a + b + c;
/* 含有new */
String k = new String(a);
String l = k.intern();
}
Jad编译后:
public static void main(String args[])
{
String s = "abc";
String s1 = "abcdef";
String s2 = "abcdefmno";
String s3 = "trueabc";
String s4 = "5abc";
String s5 = "abc5.5";
String s6 = "asdfg";
String s7 = (new StringBuilder()).append(s5).append("abc").toString();
String s8 = (new StringBuilder()).append(s5).append(s6).toString();
String s9 = (new StringBuilder()).append(s).append(s1).append(s2).toString();
String s10 = new String(s);
String s11 = s10.intern();
}
所以我得出一个结论,在连接字符串的时候,如果不含有变量,则在编译时进行拼接,如果含有变量,则调用StringBuilder(StringBuffer) 的方法 append进行合并(实质上是新建了一个String对象)。