我面试时候答1个,后来和面试官关于这个问题讨论了半天,引用了java doc和Thinking in Java上的原文做论据,最后面试官无奈了,结果被录用了不过我没去,因为出这种面试题的面试官自己就很晕……
火了,有人搞不清楚就说我提的问题低级。 以我的判断SUN的技术人员又不是白痴。 明显我们 String s = new String("ss"); 目的是在堆里创建对象。 干吗脱裤子放屁跑到常量池里再去搞一个。 这个问题我已经问了三遍,但每次都无功而返。 做为JAVA程序员,大家不觉得这是耻辱吗? 为什么这么个小问题,怎么这么绕呢。
2个 ,创建string时最好写成 string s = "blahblah";
第一次 String s1 = new String("abc"); 时 创建 2 个对象; 第二次 String s2 = new String("abc"); 时 只创建 1 个对象。
呀,你还火了,SUN技术人员绝对不是白痴是肯定的了,自己到Think in java 里去找吧。
如池中没有"ss",就必须先创建一个,然后new一个s,如果有就不必了
建议看看源代码吧 /** * Initializes a newly created <code>String</code> object so that it * represents the same sequence of characters as the argument; in other * words, the newly created string is a copy of the argument string. Unless * an explicit copy of <code>original</code> is needed, use of this * constructor is unnecessary since Strings are immutable. * * @param original a <code>String</code>. */ public String(String original) { int size = original.count; char[] originalValue = original.value; char[] v; if (originalValue.length > size) { // The array representing the String is bigger than the new // String itself. Perhaps this constructor is being called // in order to trim the baggage, so make a copy of the array. v = new char[size]; System.arraycopy(originalValue, original.offset, v, 0, size); } else { // The array representing the String is the same // size as the String, so no point in making a copy. v = originalValue; } this.offset = 0; this.count = size; this.value = v; }可以看看注释上的这句话:Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable. 除非有必要显式地生成 original 的副本,否则就没有必要使用这个构造,这因为 String 是不可变的。
确实搞笑. 有些无知的人偷换概念就以为自己真的懂了. 编译期常当然是一个对象,但它不是String s = new String("xyz");这一行代码创建的.它如何创建是根据编译需要来决定的,如果在这一行上面还有其它地方也引用这个常量,那么在编译到那个地方的时候它就要插入常量编译的处理.即使仅有这一行代码,它的产生也是在编译期产生的,附着在class文件中 你载入类的时候那个常量就已经存在了,即使你不运行这一行代码所在的方法,那个常量也是存在的.所以题目问题的是这一行代码产生几个String对象.当然是问这一行代码在运行的时候产生几个String对象. 当然是产生1个.1.那个编译期常量不一定是由这行代码引用而产生,不有说是这行代码运行所产生的. 2.那时仅有这一行代码引用那个常量,它的存在也不因这一行代码的运行而产生.所以,请SB们看清楚,我说的是String s = new String("xyz");这一行代码运行时只产生一个String对象,并不是某些不懂装懂的说常量池中的String不是对象.而是它和这一行代码的运行无关!这道的标准解释,sun自己的SCJP上有专相同的题目,只是下面多了一个操作:String str = new String("xyz"); str = str.substring(2); 问题一模一样,sun自己的答案是2个,显然他根本没有把编译期常量看成是这两行代码运行时产生的.除非脑子有问题.
楼主有问是运行时创建了几个对象吗?他的意思明显是这样的语句会导致jvm创建几个对象,你说的东西很多人都知道,别以为别人都是傻子。 楼主有说过之前已经创建"xyz"常量吗?你非要说“如果在这一行上面还有其它地方也引用这个常量”,不觉得可笑吗? 难道一定要问:public test{ public static void main(string args[])} String str = new String("xyz"); } }这样的程序从编译到运行一共产生多少个对象,你才能理解楼主的问题?你说String str = new String("xyz")这句话在运行的时候产生了一个对象,我有说你错吗?可是你用这个答案来回答楼主,并且说别人都是不懂装懂,那么你这个答案对于楼主的问题是对的?人人都可以看出来你在否定编译期常量是作为本题答案的一个对象的意思。SUN的这个问题: String str = new String("xyz"); str = str.substring(2); 答案是2,这个2指的是哪2个对象你自己好好想清楚了,别到时候别人笑死都不知道。在这边提问和回答的人都是学习者,45楼说了,别那么粪青,我到不觉得你肤浅,而是有知识没文化这样的月经题那么多,从来没有人说编译期产生的常量对象不算在答案中的,而且楼上部分楼已经回答的很好了,如果你有自己的见解,你可以提出来,但是你说别人是SB,那我只能说:神经病医院最近走丢一个人,请大家注意。
一个SCJP题目11. public String makinStrings() { 12. String s = “Fred”; 13. s = s + “47”; 14. s = s.substring(2, 5); 15. s = s.toUpperCase(); 16. return s.toString(); 17. } How many String objects will be created when this method is invoked? 答案是3个。"Fred","47"是字符串字面常量,它们在在类加载时创建的。这里题目问,"方法调用时"有多少个String对象被创建,两个字面常量自然不包括在内。3个是:"Fred47","ed4","ED4"。
11. public String makinStrings() { 12. String s = “Fred”; 13. s = s + “47”; 14. s = s.substring(2, 5); 15. s = s.toUpperCase(); 16. return s.toString(); 17. } How many String objects will be created when this method is invoked? 答案是3个。"Fred","47"是字符串字面常量,它们在在类加载时创建的。这个怎么是在类加载时创建的呢? 类加载时就没有调用方法,而String s = "Fred",就是一个临时变量,当然要调用方法进才用到的。非常费解。
搞笑呢。
你们的意思是在常量池里也产生了一个对象。
new 一下在堆里有产生了一个对象??
1个是“xyz”
一个是new
1个是“xyz”
一个是new
补充下原因:
在写“xyz”时候就已经创建了一个String类型的对象而new String(“xyz”)又创建了一个String对象
而指向存储数据的指针存储在栈内存。上边的例子,S 为指针 为一个对象,xyz 为数据 为一个对象,栈内存记录的指针指向xyz的地址。
很到位,一切都是对象,包括reference。
创建了“xyz”, s只是有个饮用指向了“xyz”。
错错错
使用到 你知不知道 引用类型 引用类型 当你使用new关键字的时候 就已经在内存中 创建了一个副本出来了
对象名 只是用来引用的 你引用的并不是本类 而是你创建出来的副本!!
以我的判断SUN的技术人员又不是白痴。
明显我们
String s = new String("ss");
目的是在堆里创建对象。
干吗脱裤子放屁跑到常量池里再去搞一个。
这个问题我已经问了三遍,但每次都无功而返。
做为JAVA程序员,大家不觉得这是耻辱吗?
为什么这么个小问题,怎么这么绕呢。
String s1 = new String("abc");
时 创建 2 个对象;
第二次
String s2 = new String("abc");
时 只创建 1 个对象。
呀,你还火了,SUN技术人员绝对不是白痴是肯定的了,自己到Think in java 里去找吧。
如池中没有"ss",就必须先创建一个,然后new一个s,如果有就不必了
* Initializes a newly created <code>String</code> object so that it
* represents the same sequence of characters as the argument; in other
* words, the newly created string is a copy of the argument string. Unless
* an explicit copy of <code>original</code> is needed, use of this
* constructor is unnecessary since Strings are immutable.
*
* @param original a <code>String</code>.
*/
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
v = new char[size];
System.arraycopy(originalValue, original.offset, v, 0, size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}可以看看注释上的这句话:Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.
除非有必要显式地生成 original 的副本,否则就没有必要使用这个构造,这因为 String 是不可变的。
实在常量区中存放一个"xyz"对象 引用s指向它 0: ldc #2; //String xyz
2: astore_1
3: return
2、String s = "xyz";
String s2="xyz"; ****************** 还是一个对象
实在常量区中存放一个"xyz"对象
s s2两个引用都指向它 0: ldc #2; //String xyz
2: astore_1
3: ldc #2; //String xyz
5: astore_2
6: return
3、String s = new String("xyz"); ****************** 两个对象
常量区一个"xyz"对象, 堆区一个String对象,内容为"xyz"
引用s指向堆区的String对象 0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String xyz4、
String s = new String("xyz");
String t="xyz"; ****************** 还是两个对象
s指向堆区的对象,t指向常量区对象,后面不论有多少String的引用赋值为"xyz",都是指向常量区的对象
引用t 看下面第10行,比较第4行 0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String xyz
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin
)V
9: astore_1
10: ldc #3; //String xyz
12: astore_2
13: return
5、String s = new String("xyz");
String t="xyz";
String s2=new String("xyz"); ****************** 三个对象
常量区1个 堆区两个 0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String xyz
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin
)V
9: astore_1
10: ldc #3; //String xyz
12: astore_2
13: new #2; //class java/lang/String
16: dup
17: ldc #3; //String xyz
19: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin
)V
22: astore_3
23: return
就这些吧 不懂得可以去看看ldc和String常量池
常量区一个"xyz"对象, 堆区一个String对象,内容为"xyz" 如何验证常量区有一个对象。。
一群不懂装懂的,没有一个是真的懂,即使有些人以为懂了。
这个问题真正的答案是创建了一个String对象。
那个字面值“xyz”是编译期常量,根本不能叫“代码创建的对象”。就象JVM后台的GC线程,我们不能说是JAVA程序的多线程,因为它对程序员是不可访问的。
编译期常量当你loadClass的时候已经存在,而不是这行代码运行时候创建的,而题目问的是这行代码创建了几个String,当然是1个。
不懂其实不要紧,可以学习,最搞笑的是不懂以为很懂。
指向的是new String 所在的堆空间。
那个字面值“xyz”是编译期常量,根本不能叫“代码创建的对象”。在问你一句,如果这句话不存在,那个常量还存在不?
疯了。
问了我们实验室,非常老资格的程序员:
String s= new String("sss");
仅仅生成一个对象。
就楼主说的问题,执行这条语句后新创建了一个String对象.
答案就是2个,编译期常量池一个,运行期栈区new一个
有些无知的人偷换概念就以为自己真的懂了.
编译期常当然是一个对象,但它不是String s = new String("xyz");这一行代码创建的.它如何创建是根据编译需要来决定的,如果在这一行上面还有其它地方也引用这个常量,那么在编译到那个地方的时候它就要插入常量编译的处理.即使仅有这一行代码,它的产生也是在编译期产生的,附着在class文件中
你载入类的时候那个常量就已经存在了,即使你不运行这一行代码所在的方法,那个常量也是存在的.所以题目问题的是这一行代码产生几个String对象.当然是问这一行代码在运行的时候产生几个String对象.
当然是产生1个.1.那个编译期常量不一定是由这行代码引用而产生,不有说是这行代码运行所产生的.
2.那时仅有这一行代码引用那个常量,它的存在也不因这一行代码的运行而产生.所以,请SB们看清楚,我说的是String s = new String("xyz");这一行代码运行时只产生一个String对象,并不是某些不懂装懂的说常量池中的String不是对象.而是它和这一行代码的运行无关!这道的标准解释,sun自己的SCJP上有专相同的题目,只是下面多了一个操作:String str = new String("xyz");
str = str.substring(2);
问题一模一样,sun自己的答案是2个,显然他根本没有把编译期常量看成是这两行代码运行时产生的.除非脑子有问题.
楼主有说过之前已经创建"xyz"常量吗?你非要说“如果在这一行上面还有其它地方也引用这个常量”,不觉得可笑吗?
难道一定要问:public test{
public static void main(string args[])}
String str = new String("xyz");
}
}这样的程序从编译到运行一共产生多少个对象,你才能理解楼主的问题?你说String str = new String("xyz")这句话在运行的时候产生了一个对象,我有说你错吗?可是你用这个答案来回答楼主,并且说别人都是不懂装懂,那么你这个答案对于楼主的问题是对的?人人都可以看出来你在否定编译期常量是作为本题答案的一个对象的意思。SUN的这个问题:
String str = new String("xyz");
str = str.substring(2);
答案是2,这个2指的是哪2个对象你自己好好想清楚了,别到时候别人笑死都不知道。在这边提问和回答的人都是学习者,45楼说了,别那么粪青,我到不觉得你肤浅,而是有知识没文化这样的月经题那么多,从来没有人说编译期产生的常量对象不算在答案中的,而且楼上部分楼已经回答的很好了,如果你有自己的见解,你可以提出来,但是你说别人是SB,那我只能说:神经病医院最近走丢一个人,请大家注意。
"xyz"是一个,new String()是一个
先创建"xyz"然后再用new String把"xyz"封一下放到S里面
SUN的这个问题:
String str = new String("xyz");
str = str.substring(2); 对象都有哪几个?
还一个是在string pool里面,也是xyz...
因为你创建的时候,string pool里面没有xyz这个所以string pool里面就会创建一个xyz,再复制给那个new的。
但就我所知道的
String s = new String("xyz");
这行代码
创造了一个对象也许是指变量?楼主的意思是都算?
你说SCJP上边有原题,那么问下:
原题是怎么写的?
创建了几个对象?
和创建过几个对象?
好象不会是同一个意思的。
有这个东西吗??
谁有发我一个?
[email protected]
我也在想,如果有工具可以比较明确的告诉你,那大家还在这里费口蛇干吗?
12. String s = “Fred”;
13. s = s + “47”;
14. s = s.substring(2, 5);
15. s = s.toUpperCase();
16. return s.toString();
17. }
How many String objects will be created when this method is invoked? 答案是3个。"Fred","47"是字符串字面常量,它们在在类加载时创建的。这里题目问,"方法调用时"有多少个String对象被创建,两个字面常量自然不包括在内。3个是:"Fred47","ed4","ED4"。
http://blog.csdn.net/silentbalanceyh/archive/2009/10/13/4661230.aspx
送给楼主,私人BLOG上整理的一份,看了就明白了!
12. String s = “Fred”;
13. s = s + “47”;
14. s = s.substring(2, 5);
15. s = s.toUpperCase();
16. return s.toString();
17. }
How many String objects will be created when this method is invoked? 答案是3个。"Fred","47"是字符串字面常量,它们在在类加载时创建的。这个怎么是在类加载时创建的呢?
类加载时就没有调用方法,而String s = "Fred",就是一个临时变量,当然要调用方法进才用到的。非常费解。
我记得没错的话
这个内存管理器
是java自带的一玩意儿
不是什么工具
“这行代码”只是十几个字符而已,它怎么能产生字符串?我不知道有多少人理解“这么代码产生字符串”不是理解成“这行代码的运行产生字符串”?
当然脑子和一般人不一样的除外。思维正常的人理所当然地理解成“这行代码在运行的时候产生几个字符串”。如果说在编译期产生的也算上,那么byteCode被JIT编译产生的本地代码中字符串算不算?
这样的思维已经搞笑到低级的层次。当然在没有神来做裁决的时候(即时一个先圣和一个无知人,在他们两个人中也没有谁能说服谁),SUN的标准解释难道不足以说明这它产生一个字符串?