m0_65506053 2022-01-04 22:12 采纳率: 88.9%
浏览 32
已结题

专家解答一下为什么在第二十行代码对p的name属性改了以后,p2的name属性还是milan,而没有变成和p的一样是xyz?



```java
    //编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。克隆对象, 
    //注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同
public class test { 

    //编写一个main方法
    public static void main(String[] args) {
        
        Person p = new Person();
        p.name = "milan";
        p.age = 100;
        //创建tools
        MyTools tools = new MyTools();
        Person p2 = tools.copyPerson(p);

        //到此 p 和 p2是Person对象,但是是两个独立的对象,属性相同
        System.out.println("p的属性 age=" + p.age  + " 名字=" + p.name);
        System.out.println("p2的属性 age=" + p2.age  + " 名字=" + p2.name);
        //这里老师提示: 可以同 对象比较看看是否为同一个对象
        System.out.println(p == p2);//false
        p.name ="xyz";
        System.out.println("======================");//用来区分上面的输出
        System.out.println("p的属性 age=" + p.age  + " 名字=" + p.name);
        System.out.println("p2的属性 age=" + p2.age  + " 名字=" + p2.name);

    }
}

class Person {
    String name;
    int age;
}

class MyTools {
    public Person copyPerson(Person p) {
        //创建一个新的对象
        Person p2 = new Person();
        p2.name = p.name; //把原来对象的名字赋给p2.name
        p2.age = p.age; //把原来对象的年龄赋给p2.age
        return p2;
    }
}
在学习方法的内存机制的时候,教程说对象中的属性如果是字符串,那么这个字符串会存放在方法区,在对象中存的是存字符串的地址,那么如果是这样的话,p对象改name属性的时候,方法区中的字符串会变成xyz,那么访问p2对象的name应该也会变成xyz才对呀,因为访问name的时候是一个地址,到地址中去找位于方法区的字符串变成了xyz,但是通过运行代码发现,p2的name依然是milan,并没有变成xyz,麻烦解答一下,谢谢

  • 写回答

1条回答 默认 最新

  • 穆瑾轩 2022-01-04 22:57
    关注

    当然,你能理解内存模型亦或是理解堆栈相关知识,其实就蛮好理解的。
    p2.name = p.name; 这里赋值,对于引用类型,只是将p2.name的引用 指向了p.name引用的那块内存地址中的值。此时他们指向的是内存中的同一个地址。
    p.name ="xyz"; 当你把p.name重新赋值,并不是将原来的地址的值改变了,而是将p.name指向了内存中所谓的"xyz"的这个地址。此时p.name和p2.name的指向是不同的地址,当然就不一样了。
    在内存模型中,堆是线程共享的(引用类型,如对象,类中的全局变量),而栈是线程私有的(常见的有局部变量)。你所说的是改变栈中的值,那就会一起变。引用类型赋值改变的是内存地址,也就是一个引用指向。要真正改变内存堆中或常量池中的值才会真的改变。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 1月12日
  • 已采纳回答 1月4日
  • 创建了问题 1月4日

悬赏问题

  • ¥15 目详情-五一模拟赛详情页
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line