面试题答案
一键面试浅拷贝的实现方式
在Java中,实现对象的浅拷贝可以通过实现 Cloneable
接口并重写 clone()
方法来实现。Cloneable
接口是一个标记接口,它本身不包含任何方法,只是表明该类支持克隆操作。
浅拷贝出现数据不一致的场景
浅拷贝只是复制对象的基本数据类型字段,对于引用数据类型字段,只是复制了引用,而不是引用指向的对象。这就导致当原对象和拷贝对象中的引用数据类型字段指向同一个对象时,如果其中一个对象通过引用修改了该对象的状态,另一个对象也会受到影响,从而出现数据不一致的问题。
代码示例
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 int age;
private String name;
private Address address;
public Person(int age, String name, Address address) {
this.age = age;
this.name = name;
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
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 Main {
public static void main(String[] args) {
Address address = new Address("Beijing");
Person person1 = new Person(30, "Alice", address);
try {
Person person2 = (Person) person1.clone();
System.out.println("person1 address: " + person1.getAddress().getCity());
System.out.println("person2 address: " + person2.getAddress().getCity());
// 修改person2的地址
person2.getAddress().setCity("Shanghai");
System.out.println("After modification:");
System.out.println("person1 address: " + person1.getAddress().getCity());
System.out.println("person2 address: " + person2.getAddress().getCity());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
在上述代码中,Person
类包含基本数据类型 age
和 name
以及引用数据类型 Address
。Person
类实现了 Cloneable
接口并重写了 clone()
方法。在 main
方法中,创建了 person1
对象并克隆出 person2
对象,然后修改 person2
的 Address
中的 city
,可以看到 person1
的 Address
中的 city
也发生了变化,这就是浅拷贝导致数据不一致的情况。