黑马程序员技术交流社区
标题:
在内存中赋值的问题
[打印本页]
作者:
whocases
时间:
2012-6-28 19:36
标题:
在内存中赋值的问题
本帖最后由 whocases 于 2012-6-29 11:51 编辑
先看下代码
class Demo{
String temp = "hello" ; // 此处为了方便,属性暂时不封装
};
public class RefDemo{
public static void main(String args[]){
Demo d1 = new Demo() ; // 实例化Demo对象,实例化
System.out.println("fun()方法调用之后:" + d1.temp) ;
}
public static void fun(Demo d2){ // 此处的方法由主方法直接调用
d2.temp = "itcast"; // 修改temp值
}
};
我想问的是 当String作为一个类的成员时 它在堆中具体是怎么回事
比如 上述代码中 d2.temp = "itcast"; 修改Sring类对象时 是不是一样先是创建一个匿名对象 再用temp引用它。。。??如果是这样 那么是不是 原来的“hello”就成垃圾了。。。
作者:
赵倩倩
时间:
2012-6-28 19:43
这可以参考下经典的面试题,
1.String 和 StringBuffer的区别,
2.String s = “A” + “B”;的过程中产生了几个String对象
这些题目考察的重点其实就是,String是不可再分配的,如果是对一个字符串做出修改,实质上是创建了一个新的字符串。原来的字符串变成了垃圾
这也是为什么在循环操作String的时候,要尽量使用StringBuffer或StringBuilder的原因。
作者:
孙飞
时间:
2012-6-28 22:08
String是一个特殊的包装类数据。可以用String str = new String("abc");的形式来创建;也可以用String str = "abc";的形式来创建。第一种方式 是每new 一人对象 就在堆内存中开辟一块空间来存放new出来的对象,再把对象的地址指向栈内存中的引用变量str,和普通对象创建的过程一样。第二种方式 是先定义一个名为str的对String类的对象引用变量:String str;在栈中查找有没有存放值为“abc”的地址,如果已经有了值为“abc”的地址,则查找对象,并返回对象的地址给str。如果没有,则开辟一个存放字面值为“abc”的地址,接着在堆内存中创建一个新的String类的对象,并将对象的字符串值指向这个地址。d2.temp = "itcast";中给temp赋了新的对象的地址,原来的hello就没有指向它的引用,就成为了垃圾了。
作者:
孙飞
时间:
2012-6-28 22:09
本帖最后由 feigecal 于 2012-6-30 21:38 编辑
String是一个特殊的包装类数据。可以用String str = new String("abc");的形式来创建;也可以用String str = "abc";的形式来创建。第一种方式 是每new 一人对象 就在堆内存中开辟一块空间来存放new出来的对象,再把对象的地址指向栈内存中的引用变量str,和普通对象创建的过程一样。第二种方式 是先定义一个名为str的对String类的对象引用变量:String str;在栈中查找有没有存放值为“abc”的地址,如果已经有了值为“abc”的地址,则查找对象,并返回对象的地址给str。如果没有,则开辟一个存放字面值为“abc”的地址,接着在堆内存中创建一个新的String类的对象,并将对象的字符串值指向这个地址。d2.temp = "itcast";中给temp赋了新的对象的地址,原来的hello就没有指向它的引用,但还在内存中存在,。
作者:
游洪波
时间:
2012-6-28 22:51
本帖最后由 游洪波 于 2012-6-28 22:53 编辑
我给你画了一张针对你这个类的内存使用示意图,相信你看完以后就会明白了
图片1.jpg
(38.41 KB, 下载次数: 29)
下载附件
2012-6-28 22:52 上传
应为你现在的Demo是一个对象,而String类型的变量只是对象中的一个属性,所以操作它不会在内存中开辟新的空间,而是在Demo被实例化的时候会开辟一个空间里边有一个String 的属性而已
作者:
常佳杰
时间:
2012-6-28 23:34
public class Test15 {
public static void main(String args[]) {
Demo d1 = new Demo(); // 实例化Demo对象,实例化
System.out.println("fun()方法调用之后:" + d2.temp);//
这你标记的是"fun()方法调用之后:"可你并不是输出的调用之后的..
}
public static void fun(Demo d2) { // 此处的方法由主方法直接调用
d2.temp = "itcast"; // 修改temp值
}
}
class Demo {
String temp = "hello"; // 此处为了方便,属性暂时不封装
}
想输出调用之后的改成这样:
package com.heima.changjiajie;
public class Test15 {
public static void main(String args[]) {
Demo d1 = new Demo(); // 实例化Demo对象,实例化
Demo d2 = new Demo();
Test15.fun(d2);
System.out.println("fun()方法调用之后:" + d2.temp);
}
public static void fun(Demo d2) {
d2.temp = "itcast";
}
}
class Demo {
String temp = "hello";
}
那不是修改String类的对象只是改了引用的内容(也就是堆里存的内容),是创建了新的Demo对象...
楼上的已经说了 没有指向它的引用了,也就成为垃圾了...
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2