黑马程序员技术交流社区
标题: 关于字符串在内存中存放位置的问题。 [打印本页]
作者: 张淼 时间: 2012-9-18 23:28
标题: 关于字符串在内存中存放位置的问题。
编译并运行以下代码的输出结果是?( )
String s1 = new String("amit");
System.out.println(s1.replace('m','r'));
System.out.println(s1);
String s3 = "arit";
String s4 = "arit"; //s3与s4的地址相同,那么 s3==s1 这个判断是否也为 ture呢?
String s2 = s1.replace('m','r'); //既然字符串池中不能有重复的元素,那么s2所代表的"arit"在池中已经存在,那么s2是不是应该与s3和s4是拥有同一地址值?
System.out.println(s2 == s3);
System.out.println(s3 == s4);
A. arit
amit
false
true
B. arit
arit
false
true
C. amit
amit
false
true
D. arit
amit
true
true
作者: 谭立文 时间: 2012-9-18 23:53
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = count;
int i = -1;
char[] val = value; /* avoid getfield opcode */
int off = offset; /* avoid getfield opcode */
while (++i < len) {
if (val[off + i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0 ; j < i ; j++) {
buf[j] = val[off+j];
}
while (i < len) {
char c = val[off + i];
buf = (c == oldChar) ? newChar : c;
i++;
}
return new String(0, len, buf);
}
}
return this;
}
这是replace方法的源代码,从中可以看出,其实返回的是一个新new出来的String对象的引用,这样就很好理解了,说明Java虚拟机根本就没有对replace的返回结果进行缓存。
作者: 夏天 时间: 2012-9-19 00:27
首先,字符串对象是一个常量,存放于常量池中。什么是常量,就是不可变的。
String s1 = new String("amit");
System.out.println(s1.replace('m', 'r'));
//先说这个,其实这句话相当于 String s2=s1.replace('m', 'r'); 再输出S2,这只是另外一个对象
//记得常量是不能改变的。所以不管你输出什么,s1没变
String s3 = "arit";
String s4 = "arit";
System.out.println(s3 == s4);
再说这个,既然是常量池,所以s3和s4指向同一对象,输出s3==s4,肯定是true。
System.out.println(s2 == s3);
再说困惑你的最后一个问题。
String s2=s1.replace('m', 'r'); //replace源码返回的其实是一个新new的字符串。
也就是相当于下面的比较:
String a="abc";
String b=new String("abc");
所以输出s2==s3是 false。
作者: 冯心程 时间: 2012-9-19 02:15
//s3与s4的地址相同,那么 s3==s1 这个判断是否也为 ture呢?
字符串在常量池中,如果池中已有存在的对象就不会再创建一个新的了
所以S3和S4指向的是同一个 所以为true
String s2 = s1.replace('m','r');
这句话实际上是在内存中创建了一个新的对象并返回把这个新句柄赋给S2,
再实际点这句话根本上是在内存产生的是2个对象(毕老师视频里有说过)一个是在堆内存中,一个是在池中
所以两个不同对象当然是false
作者: 吴通 时间: 2012-9-19 03:05
本帖最后由 吴通 于 2012-9-19 03:12 编辑
答案选A
首先我们要知道对于String类
(1)String s1="abc"; String s2="abc";
这种情况下,首先会在内存中查找看String池中有没有"abc"对象,如果有的话,就不会再创建新的对象,只是返回它的引用,如果没有的话才会创建该类对象
(2)String s=new String("abc");
这种情况下由于new了对象,所以不管String池中有没有该类对象都会再次创建该对象
String s1 = new String("amit"); //在内存中创建了一个String对象"amit" System.out.println(s1.replace('m','r')); //用replace语句把amit中的m替换为r,所以打印"arit" System.out.println(s1); //由于String类的对象不会被改变,所以s1对象不会改变还是"amit" String s3 = "arit"; //创建s3对象"arit" String s4 = "arit"; //创建s4对象"arit",上面总结的(1)可以看出,s3对象和s4对象其实都是一个对象,因为内存中只创建了一次,它们引用相同
String s2 = s1.replace('m','r'); //不是说线程池中不能有重复的元素,像(2),加入线程池中有"abc"对象,还是会创建的,其实这个替换的语句就
相当于重新创建对象,因为原有的对象不可能改变,只有创建新的对象
System.out.println(s2 == s3); //由于s2相当于创建了一个新的对象,所以两个对象地址值是不相同的,所以为false
System.out.println(s3 == s4); //s3和s4的引用指向了同一个对象,所以地址值相同,为true
所以答案为
A. arit amit false true |
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |