java引用问题

xiongjin1983 2010-02-24 11:39:29
看代码

public class Test {

public static void main(String[] args) {

Test test = new Test();
test.arrayTest();
}

public void arrayTest() {
Object[] os = new Object[10];
os[0] = new Person("A");

Person per1 = (Person) os[0];
Person per2 = (Person) os[0];
Person per3 = per1;

per1.setName("B");
per1 = null;
os[0] = null;
System.out.println(per1);
System.out.println(per2);
System.out.println(per3);
}
}

class Person {
private String name;

public Person(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String toString() {
return this.name;
}
}
为什么打印结果为
null
B
B
...全文
129 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiongjin1983 2010-02-24
  • 打赏
  • 举报
回复
per1==per2 和per2==per3都是为true
如果象你
per2 = new Person("A");
per3 = new Person("A");
那么per2==per3就应该为false了

我的理解是per1和per2和per3都指向同一引用,当把per1为null时,其他都应该为null啊,就像把per1的name修改为B时,其他两个值都修改了
jafapple 2010-02-24
  • 打赏
  • 举报
回复
Person per1 = (Person) os[0]; //指向 “os[0]指向的内存区域”
Person per2 = (Person) os[0]; //指向 “os[0]指向的内存区域”
Person per3 = per1; //指向 “os[0]指向的内存区域”

per1.setName("B"); //设置name="B"
per1 = null; //per1指向空, 但“os[0]指向的内存区域”还被per2,per3对象引用着
os[0] = null; //os[0]指向空地址。

到这里你就明白了吧,
System.out.println(per1); per1对象指向空地址,直接输出
System.out.println(per2);
System.out.println(per3); 这是调用Person.toString方法
zhaining522 2010-02-24
  • 打赏
  • 举报
回复
因为 打印的时候是这样的一个情况


per1 = null;
os[0] = null;
per2 = new Person("A");
per3 = new Person("A");
keeya0416 2010-02-24
  • 打赏
  • 举报
回复
引用 9 楼 xiongjin1983 的回复:
谢谢各位的解答
看我这么理解是不是正确的:
java中有堆栈和堆,堆栈主要存储引用,而堆中主要存储对象,就比如per1 per2这为引用,存储在堆栈中,而new Person("A")为对象,存储在堆中。
实际上per1 per2 per3 os[0]都是指向new Person("A")的空间,当执行per1=null 或 os[0]=new Person("B")时,实际上是把per1,os[0]指向另外的堆空间,对per2 per3并没有影响;而 per1.setName("B"),则是直接修改指向对象的值.

对 就是这个意思
xiongjin1983 2010-02-24
  • 打赏
  • 举报
回复
谢谢各位的解答
看我这么理解是不是正确的:
java中有堆栈和堆,堆栈主要存储引用,而堆中主要存储对象,就比如per1 per2这为引用,存储在堆栈中,而new Person("A")为对象,存储在堆中。
实际上per1 per2 per3 os[0]都是指向new Person("A")的空间,当执行per1=null 或 os[0]=new Person("B")时,实际上是把per1,os[0]指向另外的堆空间,对per2 per3并没有影响;而 per1.setName("B"),则是直接修改指向对象的值.
FANG5566DAN 2010-02-24
  • 打赏
  • 举报
回复
楼上说的对,还是画个内分分析图吧!那样清晰明了!
hiqrf 2010-02-24
  • 打赏
  • 举报
回复
自已画个内存模拟图,一下子就明白了...
wslzxql 2010-02-24
  • 打赏
  • 举报
回复
引用 2 楼 jafapple 的回复:
Person per1 = (Person) os[0]; //指向 “os[0]指向的内存区域”
Person per2 = (Person) os[0];  //指向 “os[0]指向的内存区域”
Person per3 = per1;            //指向 “os[0]指向的内存区域”

per1.setName("B");  //设置name="B"
per1 = null;      //per1指向空, 但“os[0]指向的内存区域”还被per2,per3对象引用着
os[0] = null;      //os[0]指向空地址。

到这里你就明白了吧,
System.out.println(per1);  per1对象指向空地址,直接输出
System.out.println(per2);
System.out.println(per3);  这是调用Person.toString方法



同意
keeya0416 2010-02-24
  • 打赏
  • 举报
回复
引用 3 楼 xiongjin1983 的回复:
per1==per2 和per2==per3都是为true
如果象你
per2 = new Person("A");
per3 = new Person("A");
那么per2==per3就应该为false了

我的理解是per1和per2和per3都指向同一引用,当把per1为null时,其他都应该为null啊,就像把per1的name修改为B时,其他两个值都修改了

不能这么理解的,当把per1为null时只是把per1的引用指向空了,其它两个还是指的原来那个对象在堆中的地址,per1在栈中的值变了是不会影响到栈中其它2个引用的地址的撒。
就像把per1的name修改为B时,其他两个值都修改了只是你当前的引用通过地址改变了堆中的值,类似指针的作用,所以其它2个指向相同地址的引用对应的属性也改变了
tiamay 2010-02-24
  • 打赏
  • 举报
回复
都是因为:per1.setName("B");
per1 = null;
os[0] = null;

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧