看到论坛里有个 IBM面试的帖子:
           String s = "a" + "b" + "c" + "d" + "e"; 
          问此语句共创建了几个对象,据说是10个,请专家点评   刚开始也没弄明白,然后查了下 java编程思想,
   现在认为:String 的内部结构是通过StringBuilder实现的!  所以没有生成ab abc 等对象 
             s引用在堆栈里,肯定不是对象
             所以只创建了一个对象abcde 不知道对否

解决方案 »

  1.   

    一个,
    String s = "a" + "b" + "c" + "d" + "e"; 
    在虚拟机中,被解释为:String s=(new StringBuffer().append("a").append("b").append("c")...).toString();
    因此,只产生了一个对象
      

  2.   

    被编译器编译成String s=(new StringBuffer().append("a").append("b").append("c")...).toString();
      

  3.   

    只说最后一次,只有1个。
    如果你认真的看过了Thinking In Java,你应该学到的不是记住使用StringBuilder来连接这个结论,应该学习的是作者分析问题的方法,我记得书中用的方法是javap -c 类名
    你自己试试看,看看有StringBuilder出现吗?
      

  4.   

    一样的问题。楼主好好看看吧。。有位高手回答为9个。个人感觉挺有道理的。。
    http://topic.csdn.net/u/20081129/21/050c006b-e41f-45af-aa2f-120ca4d6e55d.html
      

  5.   

    append("a") a不会在栈中创建一个String类型的对象吗??我对这方面不是很懂。还麻烦高手解释一下。。
    谢谢了。。
      

  6.   

    因为编译器在编译时就会进行优化的将其合并掉了。如果连接的是常量或者是被 final 修饰过的成员变量或者局部变量,编译器就比较聪明,都会将它们进行优化合并的。比如:String str = "a" + 1;在编译器编译完成后,会合并成为 "a1" 的字符串。再比如:
    final String s = "b";
    String str = "a" + s;这样的话,在编译器完成后也会合并成 "ab" 这个字符串,这时的被 final 所修饰的那个字符串 "b" 还是不存在的。
      

  7.   

    我看了一下这段代码的处理方式
    String str="a"+"b"+"c"+"d"+"e";
    str+="abc";先在常量池中定义一个String "abcde";
    然后new一个StringBuilder对象
    然后调用String.valueOf("abcde");方法,把常量池中的abcde取出来
    再调用StringBuilder("abcde")构造方法初始化StringBuilder
    再在常量池中定义一个"abc"字符串
    调用StringBuilder对象的append("abc")方法
    接着就是StringBuilder的toString方法返回"abcdeabc"
    然后把"abcdeabc"存入常量池把之前的"abcde"覆盖掉。在这期间建立了"abcde"一个对象,"abc"一个对象,StringBuilder一个对象,最后toString方法有生产一个"abcdeabc"对象
    一共四个对象。
      

  8.   

    问题1:String str = "a";这句话创建了几个对象?
    问题2:String str = new String("a");这句话创建了几个对象?
      

  9.   

    源代码
      public class a{
        public static void main(String[] args){
      String s = "a" + "b" + "c" + "d" + "e"; 
      System.out.println(s);
      }
    }反编译的结果
    Compiled from "a.java"
    public class a extends java.lang.Object{
    public a();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   returnpublic static void main(java.lang.String[]);
      Code:
       0:   ldc     #2; //String abcde  直接是abcde
       2:   astore_1
       3:   getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;
       6:   aload_1
       7:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       10:  return}显然只有一个abcde,不知道10个是怎么编译出来的
      

  10.   

    String s = "a" + "b" + "c" + "d" + "e"; 
    被编译成:String s = "abcde",而不是String s=(new StringBuffer().append("a").append("b").append("c")...).toString(); 
    只有当表达式中出现变量时,才会被编译成StringBulder.append的形式
    所以这条语句,最多导致一个字符串对象的创建。
      

  11.   

    如果是
    String s1 = "a";
    String s2 = "b";
    String s = s1 + "," +s2;
    那么,这时会建几个对象,特别是第3行
      

  12.   


    答:自从人们知道,String的+被解释成:StringBulder类的append(..)之后,到那儿都这是这个.害人啦!学东西,一定要理解它的真正的本质啊.知道JAVAC编译器有一个基本的"合并已知量"的优化功能否?对于编译时,已明确知道其值的"已知量",是直接在编译期间,生成代码之前,就已经合并了,不会再去生成目标(或中间)指令去计算的.因此:
    String s = "a" + "b" + "c" + "d" + "e"; 
    在编译期间,经过"合并已知量",在生成目标代码之前,编译程序就已经将 "a" + "b" + "c" + "d" + "e"合并成"abcde"了.它不会去生成什么StringBuilder(..)的.同样道理:
    int i=1+2+3;
    在编译期间,经过"合并已知量",在生成目标代码之前,编译程序就已经将 1+2+3合并成6了.它不会去生成什么+ 加法指令的.再如:十楼的
    final String s = "b"; 
    String str = "a" + s; 
    在编译期间,就已知:s是一个常量,JAVAC经过"合并已知量"的优化,在生成目标指令之前,由编译程序就将"a" + s合并成了"ab"了.说明:JAVAC编译程序还有其它的一些优化,不过对于其它优化:如:合并公共子表达式,运算强度削减,尤其是循环内的优化,是由JVM 服务器版(如:HoSpot Server版)的中间代码解释执行(部分生成目标本地代码)时,进行的.不是由JAVAC进行的.
      

  13.   


    但是java编程思想 上说的就是这个意思呀
      

  14.   

    这种东东只有在SCJP里考,面试的时候也常常问到
      

  15.   

    在jvm编译之前。ide都有可能给你优化成一个字符串。这种问题有什么意义?
    什么是字符串?他在内存里是什么样子的?
    java底层是c
    c有字符串这个东西吗?
      

  16.   


    问下:是不是
    String a="aaaaa";
    String s = a + "b" + "c" + "d" + "e"; 
    这样 才会用到StringBulder类的append,
      

  17.   


    答:
    是的.此时,String s = a + "b" + "c" + "d" + "e"; 
    才相当于:String s=new StringBuilder(a).append("b").append("c").append("d").append("e");另外:若写成:String s = "b" + "c" + "d" + "e"+a; 
    则相当于:String s=new StringBuilder("bcde").append(a);再另外:若a定义为:final String a="aaaaa";
    此时,String s = a + "b" + "c" + "d" + "e"; 
    相当于:String s="aaaaabcde";
      

  18.   

    答:忘记加toString()了.
    第一个应为:
    才相当于:String s=new StringBuilder(a).append("b").append("c").append("d").append("e").toString(); 
      

  19.   

    谢谢ZangXT, 根据我对jdk里intern方法阅读后的理解,字符串常量池里的string是算做对象的。
    那么~
    haojia0716关于常量池中无对象的阐述有误
    而我认同NewMoons的看法:
    "答案应该是0或者1个,取决于常量池中是否已经存在了那个字符串。"