String s1 = "a";
String s2 = "b";
String s3 = s1+s2 ;
问以上三条语句几个对象???
--------------------------------------------
以下的程序和上面的无关
--------------------------------------------String s1 = "a";
String s2 = "b";
String s3 = s1+s2 +"c";
问问以上三条语句几个对象???
--------------------------------------------
以下的程序和上面的无关
--------------------------------------------
String s1 = "a";
String s2 = "b";
String s3 = s1+s2 +"c"+"d";
问问以上三条语句几个对象???
3
3
s1+s2
s1+s2 +"c"
s1+s2 +"c"+"d"
Java中通过字符串连接的都会被认为是一个字符串,只创建一个对象即"abc"/"abcd"是一个对象,而不会去创建"c"或"c"/"d"再去连接!
2 .使用new String( "" )创建的对象会存储到heap中,是运行期 新创建的.
3 .使用只包含常量的字符串连接符如 " aa " + " aa " 创 建的也是常量,编译期就能确定,已经确定存储到String Pool中.(编译时会直接优化成"aaaa",如果String Pool 中没有"aaaa",就用""号创建一个String,直接放到Pool中,比如:String t = "a"+ "b" +"c"; 会优化成"abc",然后放入Pool中;又比如String s = "x"+"y"+ref;在编译时有部分的优化:"xy",而ref + "x" +"y"就不会有部分的优化,"+"从左到右执行,ref是变量,编译时期无法确定)
4 .使用包含变量的字符串连接符如 " aa " + s1创建的对象是运行期才创建的,存储在heap中.
综上4条,答案为:
3
4
4
http://www.javaeye.com/topic/774673
String s1 = "a"; 就创建了两个对象 一个是常量 值为“a” 一个是s1 对象的 常量a 的引用
瞎说
6
6
一 s1 s2 s3 a b
二 s1 s2 s3 a b c
三s1 s2 s3 a b "cd"
String s2 = "b"; //常量池一个对象
String s3 = s1+s2 ; //常量池一个对象 堆里一个对象String s1 = "a";//常量池一个对象
String s2 = "b";//常量池一个对象
String s3 = s1+s2 +"c";//常量池两个对象,堆里一个对象
创造过6个对象 不过堆里的"ab"字符串对应的对象失去引用 会被垃圾回收器回收String s1 = "a";//常量池一个对象
String s2 = "b";//常量池一个对象
String s3 = s1+s2 +"c"+"d"; //常量池三个对象,堆里三个对象创造过8个对象 不过堆里“ab" "abc"字符串对应的对象失去引用,被垃圾回收器回收不知道我的理解对不对。
上面打错
String s2 = "b";
String s3 = s1+s2 ;
和这样
String s1 = "a";
String s2 = "b";
String s3 = "a"+"b";
产生的对象是不同的
上面的产生了4个对象,下面的产生了3个
下面的在堆里没有产生对象。
String s3 = s1+s2 ;
String s4 = "a"+"b"; System.out.println(s3==s4);可以看出结果是false
因为一个在堆里 一个在常量池中。
{
public static void main(String[] args)
{
String str="ab";
String s1 = "a";//常量池一个对象
String s2 = "b";//常量池一个对象
String s3= "a"+"b";
String s4= s1+s2 ;
System.out.println(s3==str);
System.out.println(s4==str);
System.out.println(s3==s4);
System.out.println(s3==s4.intern());
}
}
运行结果
true
false
false
true
可以看到s3,s4引用变量指向的对象内容虽然相同,但地址不同。
说明
String s3= "a"+"b";
String s4= s1+s2 ;
产生了不同的对象,
当s4调用intern()方法,返回字符串池以后
s3==s4.intern() 就相等了。
说明s3指向堆里的对象,
s4指向字符串池里德对象。
{
String s1 = "a";//常量池一个对象
String s2 = "b";//常量池一个对象
String str="ab";}
字节码
java.lang.String s1;java.lang.String s2;java.lang.String str;StringTest1();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2; //String a
7: putfield #3; //Field s1:Ljava/lang/String;
10: aload_0
11: ldc #4; //String b
13: putfield #5; //Field s2:Ljava/lang/String;
16: aload_0
17: ldc #6; //String ab
19: putfield #7; //Field str:Ljava/lang/String;
22: returnclass StringTest2
{
String s1 = "a";//常量池一个对象
String s2 = "b";//常量池一个对象
String str=s1+s2;
}字节码java.lang.String s1;java.lang.String s2;java.lang.String str;StringTest2();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2; //String a
7: putfield #3; //Field s1:Ljava/lang/String;
10: aload_0
11: ldc #4; //String b
13: putfield #5; //Field s2:Ljava/lang/String;
16: aload_0
17: new #6; //class java/lang/StringBuilder
20: dup
21: invokespecial #7; //Method java/lang/StringBuilder."<init>":()V
24: aload_0
25: getfield #3; //Field s1:Ljava/lang/String;
28: invokevirtual #8; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
31: aload_0
32: getfield #5; //Field s2:Ljava/lang/String;
35: invokevirtual #8; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
38: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
41: putfield #10; //Field str:Ljava/lang/String;
44: returnclass StringTest3
{
String s1 = "a";//常量池一个对象
String s2 = "b";//常量池一个对象
String str="a"+"b";}
字节码
java.lang.String s1;java.lang.String s2;java.lang.String str;StringTest3();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2; //String a
7: putfield #3; //Field s1:Ljava/lang/String;
10: aload_0
11: ldc #4; //String b
13: putfield #5; //Field s2:Ljava/lang/String;
16: aload_0
17: ldc #6; //String ab
19: putfield #7; //Field str:Ljava/lang/String;
22: return
17: new #6; //class java/lang/StringBuilder
这行有了个new
也就是执行"+"操作符
new了 在堆里生成了对象
看不懂字节码,这里也就看到new了。
private static int One = '1';
public void func(){
//s1==s2==s3,字符串静态池,编译器优化
String s1 = "ab" + 1;
String s2 = 'a'+"b"+1;
String s3 = "a"+"b" +One';
}
}
注意的是:在多个字符串(3个以及3个以上)变量相加的时候,编译器会优化
String s = s1 +s2+s3+...
String s = new StringBuilder().append(s1).append(s2).append(s3).....toString();
同时要有个概念String除了toString方法外,其他方法都会创建一个新字符串对象,同样对“+”是如此,二StringBuilder的添加字符串是不会改变对象的。
eg:String s = s1+s2+s3+...+"abc";创建了几个对象?(3)