面试题答案
一键面试深克隆和浅克隆概念
- 浅克隆:
- 当对象被浅克隆时,克隆对象与原对象共享对其包含的可变对象的引用。也就是说,克隆对象中的成员变量如果是引用类型,这些引用指向的是与原对象相同的实际对象。对克隆对象或原对象中引用类型成员变量的修改,会影响到另一个对象的对应成员变量。
- 深克隆:
- 深克隆创建一个完全独立的对象副本,不仅克隆对象本身,还递归地克隆对象内部包含的所有可变对象。这意味着克隆对象和原对象在内存中是完全独立的,对其中一个对象的修改不会影响另一个对象。
浅克隆实现代码示例
class Address {
private String city;
public Address(String city) {
this.city = city;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
class Person implements Cloneable {
private String name;
private Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试代码:
public class ShallowCloneTest {
public static void main(String[] args) {
try {
Address address = new Address("Beijing");
Person person1 = new Person("Alice", address);
Person person2 = (Person) person1.clone();
System.out.println("person1 address: " + person1.getAddress().getCity());
System.out.println("person2 address: " + person2.getAddress().getCity());
person2.getAddress().setCity("Shanghai");
System.out.println("person1 address after person2 change: " + person1.getAddress().getCity());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
深克隆实现代码示例
class AddressDeepCloneable implements Cloneable {
private String city;
public AddressDeepCloneable(String city) {
this.city = city;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class PersonDeepCloneable implements Cloneable {
private String name;
private AddressDeepCloneable address;
public PersonDeepCloneable(String name, AddressDeepCloneable address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AddressDeepCloneable getAddress() {
return address;
}
public void setAddress(AddressDeepCloneable address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
PersonDeepCloneable cloned = (PersonDeepCloneable) super.clone();
cloned.address = (AddressDeepCloneable) address.clone();
return cloned;
}
}
测试代码:
public class DeepCopyTest {
public static void main(String[] args) {
try {
AddressDeepCloneable address = new AddressDeepCloneable("Beijing");
PersonDeepCloneable person1 = new PersonDeepCloneable("Alice", address);
PersonDeepCloneable person2 = (PersonDeepCloneable) person1.clone();
System.out.println("person1 address: " + person1.getAddress().getCity());
System.out.println("person2 address: " + person2.getAddress().getCity());
person2.getAddress().setCity("Shanghai");
System.out.println("person1 address after person2 change: " + person1.getAddress().getCity());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
实际使用场景
- 浅克隆场景:
- 性能优先且对象内部可变对象不会被修改:如果对象包含的引用类型成员变量在整个生命周期内不会被修改,并且对克隆操作的性能有较高要求,可以使用浅克隆。例如,一个包含只读配置信息的对象,这些配置信息在程序运行过程中不会改变,浅克隆可以节省内存和时间开销。
- 深克隆场景:
- 对象独立性要求高:当需要确保克隆对象和原对象完全独立,对其中一个对象的任何修改都不能影响另一个对象时,使用深克隆。比如在游戏开发中,克隆一个游戏角色对象,每个角色的属性(如装备、技能等,这些可能是复杂的对象)需要独立存在,不能因为克隆对象的属性改变而影响原对象,此时就需要深克隆。