看到论坛里有个 IBM面试的帖子:
String s = "a" + "b" + "c" + "d" + "e";
问此语句共创建了几个对象,据说是10个,请专家点评 刚开始也没弄明白,然后查了下 java编程思想,
现在认为:String 的内部结构是通过StringBuilder实现的! 所以没有生成ab abc 等对象
s引用在堆栈里,肯定不是对象
所以只创建了一个对象abcde 不知道对否
String s = "a" + "b" + "c" + "d" + "e";
问此语句共创建了几个对象,据说是10个,请专家点评 刚开始也没弄明白,然后查了下 java编程思想,
现在认为:String 的内部结构是通过StringBuilder实现的! 所以没有生成ab abc 等对象
s引用在堆栈里,肯定不是对象
所以只创建了一个对象abcde 不知道对否
String s = "a" + "b" + "c" + "d" + "e";
在虚拟机中,被解释为:String s=(new StringBuffer().append("a").append("b").append("c")...).toString();
因此,只产生了一个对象
如果你认真的看过了Thinking In Java,你应该学到的不是记住使用StringBuilder来连接这个结论,应该学习的是作者分析问题的方法,我记得书中用的方法是javap -c 类名
你自己试试看,看看有StringBuilder出现吗?
http://topic.csdn.net/u/20081129/21/050c006b-e41f-45af-aa2f-120ca4d6e55d.html
谢谢了。。
final String s = "b";
String str = "a" + s;这样的话,在编译器完成后也会合并成 "ab" 这个字符串,这时的被 final 所修饰的那个字符串 "b" 还是不存在的。
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"对象
一共四个对象。
问题2:String str = new String("a");这句话创建了几个对象?
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个是怎么编译出来的
被编译成:String s = "abcde",而不是String s=(new StringBuffer().append("a").append("b").append("c")...).toString();
只有当表达式中出现变量时,才会被编译成StringBulder.append的形式
所以这条语句,最多导致一个字符串对象的创建。
String s1 = "a";
String s2 = "b";
String s = s1 + "," +s2;
那么,这时会建几个对象,特别是第3行
答:自从人们知道,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进行的.
但是java编程思想 上说的就是这个意思呀
什么是字符串?他在内存里是什么样子的?
java底层是c
c有字符串这个东西吗?
问下:是不是
String a="aaaaa";
String s = a + "b" + "c" + "d" + "e";
这样 才会用到StringBulder类的append,
答:
是的.此时,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";
第一个应为:
才相当于:String s=new StringBuilder(a).append("b").append("c").append("d").append("e").toString();
那么~
haojia0716关于常量池中无对象的阐述有误
而我认同NewMoons的看法:
"答案应该是0或者1个,取决于常量池中是否已经存在了那个字符串。"