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"; 
问问以上三条语句几个对象???

解决方案 »

  1.   

    主题:请别再拿“String s = new String("xyz");创建了多少个String实例”来面试了吧
      

  2.   

    3
    3
    3
    s1+s2
    s1+s2 +"c"
    s1+s2 +"c"+"d"
    Java中通过字符串连接的都会被认为是一个字符串,只创建一个对象即"abc"/"abcd"是一个对象,而不会去创建"c"或"c"/"d"再去连接!
      

  3.   

    1 .单独使用 "" 引号创建的字符串都是常量,编译期 就已经确定存储到String Pool 中. 
    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
      

  4.   

    反编译,反编译,一目了然javap也行
      

  5.   

    这个确实牛逼,解释的很全面啊
    http://www.javaeye.com/topic/774673
      

  6.   

    怎么会是 3,3,4  
    String s1 = "a"; 就创建了两个对象 一个是常量 值为“a” 一个是s1 对象的 常量a 的引用
    瞎说
      

  7.   

    5
    6
    6
    一 s1 s2 s3 a b
    二 s1 s2 s3 a b c
    三s1 s2 s3 a b "cd"
      

  8.   

    String s1 = "a"; //常量池一个对象
    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"字符串对应的对象失去引用,被垃圾回收器回收不知道我的理解对不对。
      

  9.   

    String s3 = s1+s2 +"c";//常量池两个对象,堆里二个对象
    上面打错
      

  10.   

    String s1 = "a";
    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
    因为一个在堆里 一个在常量池中。
      

  11.   

    这样看起来更清楚public class String1
    {
    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指向字符串池里德对象。
      

  12.   

    class StringTest1
    {

    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
      

  13.   

    可以看到
    17: new #6; //class java/lang/StringBuilder
    这行有了个new
    也就是执行"+"操作符
    new了 在堆里生成了对象
    看不懂字节码,这里也就看到new了。
      

  14.   

    class Xxx{
       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)