String问题IBM面试 String s = "a" + "b" + "c" + "d" + "e";问此语句共创建了几个对象,据说是10个,请专家点评 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 猜一下。常量池中a,b,c,d,e,ab,abc,abcd,abcde,外加堆空间中s对象的引用 我就知道a,b,c,d,e,ab,abc,abcd,abcde a,b,c,d,e,ab,abc,abcd,abcde,s同意一楼的 a,b,c,d,e,ab,abc,abcd,abcde,s同意一楼的 1个。编译器编译的时候就处理为"abcde"了 。IBM也这么无聊。 就创建了一个String s = "a" + "b" + "c" + "d" + "e"; 赋值符号右边的"a"、"b"、"c"、"d"、"e"都是常量对于常量,编译时就直接存储它们的字面值而不是它们的引用在编译时就直接讲它们连接的结果提取出来变成了"abcde"该语句在class文件中就相当于String s = "abcde"然后当JVM执行到这一句的时候, 就在String pool里找如果没有这个字符串,就会产生一个 就一个。。反编译一下就知道了,编译器从一开始就把"a" + "b" + "c" + "d" + "e"处理为abcde了。。 以前看书 知道了 String s="a"+"b"+"c"等价于String s="abc"真的快忘记了幸好今天看到 否则说不定哪天笔试就栽在这种无聊的题目上 不是吧?我记得字符串相加的时候jvm内部会生成一个stringBuffer对象来存储的。 支持,这是IBM的笔试题吧,前些天我也考过了,但是我当时回答的是6个,忘了后面的组合了 为什么不是编译器在语法分析时就将"abcde"放入String常量池? 8个对象;首先由String a+String b产生对象StringBuffer ab;让后在将StringBuffer ab转化成String ab对象.换而言之。第一次+操作生成2个对象。同时对象String a,String b为NULL;后面过程与前面一致。一共8个对象。4个可变StringBuffer ab,abc,abcd,abcde;4个不可变长度String ab,abc,abcd,abcde;一共8个对象。当然其中+作为一种符号,a,b,c,d,e在做+法的时候做为参数传递到堆栈。这个应该不算是特地产生的。是本 各位回答的让我莫衷一是啊!到底是几种,有没有个给出正解的!刚学java很迷惑啊! 常量池中a,b,c,d,e,ab,abc,abcd,abcde,外加堆空间中s对象的引用外加堆空间中s对象的引用-->是不是应该替换为object对象牙,此时父类应该也被实例化出一个对象呀,是不是?总共加起来10个 都说了一个了哪又来了10个了,编译时就拼成了 abcde 哈哈,我日你们到底说是几个咯??一会10个,一会1个,一会8个的老子明天去sun公司问前台,你们哪个跟我一起去咯??我在人民大学西门这边,出来集合 呵呵 我支持a b c d e ab abc abcd abcde s10个 电脑是个低能儿 除非你告诉它 "a"+"b"+"c"+"d"+"e" 就是 "abcde"不然它肯定会去做 "a"+"b"+"c"+"d"+"e"; 还有,各位 java编译器 并不是 javac ,javac只是吧我们写的源代码变成字节文件 并且检查语法。java的编译环境叫JVM。java的编译器叫 JIT 即时编译器。用一点编译一点。还记得吗? 部分支持13楼,但结果还是支持1楼String都是常量,定义后不能更改内容,我们更改的只是引用。单独的"a",也有其引用和分配空间,"a"+"b"也会分配新的空间和新的引用。所以 a,b,ab,c,abc,d,abcd,e,abcde,s刚才在想要调试一下,没找到operation "+"在哪里,有没有高手指点一下。 又想到一个问题最后10个论还是1个论,s都指向"abcde",那s和"abcde"的默认引用(系统分配)算不算两个实例呢? 这个都是编译器帮忙处理掉了,所以执行的时候只有一个对象。如果懂反汇编的话用javap命令查常量池信息,如果不懂的话你用jad把class文件反编译一下看看也能得出结论。 只创建了一个, 由于进行连接的2个字符串都是常量,编译期就能确定连接后的值了所以String s = "a" + "b" + "c" + "d" + "e"; 编译器会进行优化直接把他们表示成"abcde"存储到String Pool中详情请看这个帖子,你就能明白:http://topic.csdn.net/u/20080929/02/4e0ef626-98ee-4d6d-96ed-fe40afe8290b.html 看这个程序, String s = "abcd";String s1="a"+"b"+"c"+"d";System.out.println(s==s1);打印出来是true··就说明只创建了一个对象· 被整晕了!~~ 以前理解的是 String s = "a" + "b" + "c" + "d" + "e"; 就等于 String s="abcde"; 现在彻底晕了!~~ 如果按照jvm的运行原理来说的话 1楼的是对的吧 源代码 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} 搞明白了我查了下书:java编程思想String 的内部结构是通过StringBuilder实现的! 所以没有生成ab abc 等对象s引用在堆栈里,肯定不是对象所以只创建了一个对象abcde 看看class文件就知道了。编译器已经把它优化成一个字符串了 呵呵。也曾经这么提醒过别人,不过人家说:class文件在编译之前就有了,过程还是“a”,“ab”,,。。这么来的。 http://topic.csdn.net/u/20080929/02/4e0ef626-98ee-4d6d-96ed-fe40afe8290b.html看看这个帖子吧 就 没必要在讨论了 String 不是直接存储字面值的吧。。我看书说都是引用来的。。 大家要看清题目,问此语句共创建了几个对象不管编译器最后结果还是常量池放了多少,"a"总得创建吧,"b"创建吧,"a"+"b"一样得创建... 老版本的JAVA了,早就改了。 Effective Java中建议不要用String 要用StringBuffer. 不过印象中早就改了,现在可以随意用“+” String s = "a" + "b" + "c" + "d" + "e"; 不大同意一楼和十三楼的回答,我想这样:好的,先计算=右边的表达式,注意"a","b","c","d","e";不是'a','b','c','d','e';那么每个都是String类型的一个对象,所以先在堆中建立"a","b","c","d","e"五个对象;然后,"ab","abc","abcd","abcde",再建立四个对象;一共九个对象在堆中;而String s是一个引用,建立在栈中,不是对象;只是s这个引用最终指向"abcde";所以一共九个对象,一个引用;这也是为什么,大量"+"运算的时候建议使用StringBuffer对象了;因为在这种"+"运算的过程中产生了大量的对象,为GC带来一定的开销....大概是这样的吧 only one .or more 当然,下述的只是JVM的原理,如果Java作了预编译优化,是有可能只有一个对象的,就是"abcde";所以,各位不要钻牛角尖了String s = "a" + "b" + "c" + "d" + "e"; 不大同意一楼和十三楼的回答,我想这样: 好的,先计算=右边的表达式,注意"a","b","c","d","e";不是'a','b','c','d','e';那么每个都是String类型的一个对象,所以先在堆中建立"a","b","c","d","e"五个对象;然后,"ab","abc","abcd","abcde",再建立四个对象;一共九个对象在堆中;而String s是一个引用,建立在栈中,不是对象;只是s这个引用最终指向"abcde";所以一共九个对象,一个引用;这也是为什么,大量"+"运算的时候建议使用StringBuffer对象了;因为在这种"+"运算的过程中产生了大量的对象,为GC带来一定的开销....大概是这样的吧 a,b,c,d,e,ab,abc,abcd,abcde,s同意一楼的 刚开始坚定一个,后来想想有可能两个!s,abcde; 帮我分析下这段多线程的服务端监听代码 JDBC连接ACCESS数据库……很多地方不明白? 正则表达式问题 long的除法问题,这个代码是否正确 如何把输出到System.out的文字输出到一个String中? 快速给分 Illegal start of type 是什么东东?? JNI的使用中GetIntField()参数怎么写? 有关数据流InputStream的问题 谁在啃java编程思想 请问:richard_1()? JAVA基础知识测试题 CSDN上的高手哪去了?怎么提问过没人解答啊?
常量池中a,b,c,d,e,ab,abc,abcd,abcde,外加堆空间中s对象的引用
a,b,c,d,e,ab,abc,abcd,abcde
编译器编译的时候就处理为"abcde"了 。
IBM也这么无聊。
String s = "a" + "b" + "c" + "d" + "e";
赋值符号右边的"a"、"b"、"c"、"d"、"e"都是常量
对于常量,编译时就直接存储它们的字面值而不是它们的引用
在编译时就直接讲它们连接的结果提取出来变成了"abcde"
该语句在class文件中就相当于String s = "abcde"
然后当JVM执行到这一句的时候, 就在String pool里找
如果没有这个字符串,就会产生一个
以前看书 知道了
String s="a"+"b"+"c"
等价于String s="abc"真的快忘记了
幸好今天看到 否则说不定哪天笔试就栽在这种无聊的题目上
首先由String a+String b产生对象StringBuffer ab;让后在将StringBuffer ab转化成String ab对象.换而言之。第一次+操作生成2个对象。同时对象String a,String b为NULL;后面过程与前面一致
。一共8个对象。4个可变StringBuffer ab,abc,abcd,abcde;4个不可变长度String ab,abc,abcd,abcde;
一共8个对象。当然其中+作为一种符号,a,b,c,d,e在做+法的时候做为参数传递到堆栈。这个应该不算是特地产生的。是本
总共加起来10个
都说了一个了哪又来了10个了,编译时就拼成了 abcde
哈哈,我日你们到底说是几个咯??一会10个,一会1个,一会8个的老子明天去sun公司问前台,你们哪个跟我一起去咯??我在人民大学西门这边,出来集合
不然它肯定会去做 "a"+"b"+"c"+"d"+"e";
javac只是吧我们写的源代码变成字节文件 并且检查语法。
java的编译环境叫JVM。
java的编译器叫 JIT 即时编译器。
用一点编译一点。还记得吗?
如果懂反汇编的话用javap命令查常量池信息,如果不懂的话你用jad把class文件反编译一下看看也能得出结论。
所以String s = "a" + "b" + "c" + "d" + "e"; 编译器会进行优化直接把他们表示成"abcde"存储到String Pool中详情请看这个帖子,你就能明白:
http://topic.csdn.net/u/20080929/02/4e0ef626-98ee-4d6d-96ed-fe40afe8290b.html
String s = "abcd";
String s1="a"+"b"+"c"+"d";
System.out.println(s==s1);
打印出来是true··就说明只创建了一个对象·
以前理解的是
String s = "a" + "b" + "c" + "d" + "e";
就等于
String s="abcde";
现在彻底晕了!~~
如果按照jvm的运行原理来说的话
1楼的是对的吧
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}
我查了下书:java编程思想
String 的内部结构是通过StringBuilder实现的! 所以没有生成ab abc 等对象
s引用在堆栈里,肯定不是对象
所以只创建了一个对象abcde
看看这个帖子吧
就 没必要在讨论了
String 不是直接存储字面值的吧。。我看书说都是引用来的。。
不大同意一楼和十三楼的回答,我想这样:
好的,先计算=右边的表达式,注意"a","b","c","d","e";不是'a','b','c','d','e';那么每个都是String类型的一个对象,所以先在堆中建立"a","b","c","d","e"五个对象;然后,"ab","abc","abcd","abcde",再建立四个对象;一共九个对象在堆中;而String s是一个引用,建立在栈中,不是对象;只是s这个引用最终指向"abcde";所以一共九个对象,一个引用;这也是为什么,大量"+"运算的时候建议使用StringBuffer对象了;因为在这种"+"运算的过程中产生了大量的对象,为GC带来一定的开销....大概是这样的吧
or more
不大同意一楼和十三楼的回答,我想这样:
好的,先计算=右边的表达式,注意"a","b","c","d","e";不是'a','b','c','d','e';那么每个都是String类型的一个对象,所以先在堆中建立"a","b","c","d","e"五个对象;然后,"ab","abc","abcd","abcde",再建立四个对象;一共九个对象在堆中;而String s是一个引用,建立在栈中,不是对象;只是s这个引用最终指向"abcde";所以一共九个对象,一个引用;这也是为什么,大量"+"运算的时候建议使用StringBuffer对象了;因为在这种"+"运算的过程中产生了大量的对象,为GC带来一定的开销....大概是这样的吧