如何解决Java:为什么字符串在深拷贝和浅拷贝中很特殊?
这几天我在学习 Java 的 clone
方法。我了解到 clone
使用浅拷贝。如果我想实现一个对象的深拷贝,那么我应该遵循this website
无需单独复制原语。 原始类中的所有成员类都应该支持克隆,并且在上下文中原始类的clone方法中应该对所有成员类调用super.clone()。
在我的理解中,String
在Java中是一种引用,为了更好地表达我的观点,代码如下:
// User.java
public class User implements Cloneable{
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// Getter(),setter() and toString() are omitted here
}
User user = new User();
user.setName("one");
User clone = (User)user.clone();
clone.setName("two");
System.out.println(user.getName()); // I think it should print "two",but actually "one"
因此,在我的示例中,我似乎创建了 User
(do I?)
以下是我对Java内存的理解:
①表示我创建了一个副本,②是String的变化。
所以如果我的图片是正确的,它应该打印“两个”,对吗?
我知道 java 中的 String 是不可变的,我认为这可能是发生这种情况的原因,但我不知道这是怎么发生的以及发生这种情况的原因。 >
根据@Jesper的图片,我创建了一张新图片来更具体地解释我的问题。
和演示代码:
public class Employee implements Cloneable {
private int employeeId;
private String employeeName;
private Department department;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // shallow copy
}
// Getter(),setter() and toString() are omitted here
}
public class Department{
private int id;
private String name;
// Getter(),setter() and toString() are omitted here
}
测试代码:
Department hr = new Department(1,"Human Resource");
Employee original = new Employee(1,"Admin",hr);
Employee cloned = (Employee) original.clone();
cloned.getDepartment().setName("Finance");
System.out.println(original.getDepartment().getName()); //print Finance
还有图:
红色部分是关键。如果它是 java.lang.String
对象,它将创建一个新对象(如上所示从“一”到“二”),但如果它是另一个类对象(这里是 Department
类)那么它似乎只有一个对象(而不是创建一个),所以我的问题是为什么 String 在深拷贝和浅拷贝中是 special ?这与 String
不变性有关吗?
提前致谢!
解决方法
你从这种情况开始:
然后您克隆 User
对象。您现在有两个 User
对象;变量 user
和 clone
指的是这两个对象。请注意,它们的 name
成员变量都指向同一个 String
对象,内容为 "one"
。
然后您在 setName("two")
上调用 clone
,这将更改第二个 name
对象的 User
成员变量以引用不同的 String
对象,内容为 "two"
。
注意变量 user
仍然指向 User
对象,它的 name
成员变量指向 "one"
,所以当你 System.out.println(user.getName());
是 one
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。