V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Vimax
V2EX  ›  Java

Java 的 clone 方法浅拷贝为什么不会影响 String 的值

  •  1
     
  •   Vimax · 2019-07-25 12:21:41 +08:00 · 4716 次点击
    这是一个创建于 1983 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Person 里面有两个属性String nameint age. 浅拷贝后的对象修改了 name 为什么不影响原先对象的 name?

    Person p = new Person(23, "zhang");
    System.out.println(p);
    Person p1 = (Person) p.clone();
    System.out.println(p.getName()==p1.getName());
    p1.setName="lisi"
    System.out.println(p);
    System.out.println(p.getName()==p1.getName());
    
    p[name=zhangsan, age=23]
    true
    p[name=zhangsan, age=23]
    false
    
    11 条回复    2019-07-25 23:55:51 +08:00
    HelloAmadeus
        1
    HelloAmadeus  
       2019-07-25 12:23:40 +08:00 via iPhone
    string 是不可变对象
    lhx2008
        2
    lhx2008  
       2019-07-25 12:28:22 +08:00 via Android
    第二个就不说了,肯定不等
    第一个是 string pool 的原因,你初始化的时候用了 string pool
    ninjachen
        3
    ninjachen  
       2019-07-25 12:40:34 +08:00   ❤️ 1
    p1.setName("lisi");
    执行了这个后,p1 的 name 的引用变了,string 是不可变对象,你可以认为是 p1.name = new String(lisi");
    passerbytiny
        4
    passerbytiny  
       2019-07-25 13:03:48 +08:00   ❤️ 1
    你的前四句代码与 String 无关,name 换成任何类型,最终都是 p.name=p1.name
    你的后三句代码同样与 String 无关,name 不管是任何类型,除非是执行 p1.setName(p.getName()) 或者 p1.setName(p1.getName()) ,否则把 name 换成任何新对象,都必然导致 p.getName()==p1.getName()的结果是 false。

    要想测试浅拷贝的负面结果,你需要的是调用 p1.getName().setXXX 方法。很不凑巧的是,String 是不可变类,没有 setXXX 方法。
    danjk159
        5
    danjk159  
       2019-07-25 14:50:32 +08:00
    后面设置值的时候已经把 p1 的 String 指针位置变了,但是并不影响 p 的 String 指针位置,所以 p 的数值没影响,虽然 java 没实际使用指针.但是机制上理解还是这样子说更合适,说错误怪
    wysnylc
        6
    wysnylc  
       2019-07-25 16:06:24 +08:00
    基本类型和基本类型的封装类型不使用对象的传递性质
    qwerthhusn
        7
    qwerthhusn  
       2019-07-25 16:24:20 +08:00
    你应该看看马士兵的基础视频
    palmers
        8
    palmers  
       2019-07-25 18:17:23 +08:00
    Person p1 = (Person) p.clone(); 虽然是浅拷贝但是 p1 是一个新引用,p1.setName="lisi" 只是改变了 p1 这个引用的 name 指向 并没有改变 p.name 的指向 你可能对指针这块不太熟悉, 你可以试试 画画内存图 就会非常清晰了
    serical
        9
    serical  
       2019-07-25 18:19:48 +08:00 via Android
    跟你重写 clone 方法有关,默认就是浅复制
    palmers
        10
    palmers  
       2019-07-25 18:21:43 +08:00
    通俗一点理解就是: p1.setName="lisi" 这句的含义就是 p1 的 name 属性指针从指向 "zhang" 改变指向 "lisi" , 不再指向"zhang", 所以 你看这期间对 p 对象没有一点点影响.

    还有 p1.setName="lisi" 这句代码是不是你粘贴错了? 应该是 p1.setName("lisi") 或者 p1.name = "lisi" 才对
    mmdsun
        11
    mmdsun  
       2019-07-25 23:55:51 +08:00 via Android
    你把 p1 也输出来就知道了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2748 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:54 · PVG 21:54 · LAX 05:54 · JFK 08:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.