java为什么要 对象克隆:
在程序开发时,有时可能会遇到以下情况:已经存在一个对象A,现在需要一个与A对象完全相同的B 对象,并对B 对象的属性值进行修改,但是A 对象原有的属性值不能改变。这时,如果使用Java 提供的对象赋值语句,当修改B 对象的属性值后,A 对象的属性值也将被修改。那么应该如何实现创建一个与A 对象完全相同的B 对象,但是改变B对象的属性值时A 对象的属性值不变呢?
专家解答
要实现这一功能,可以使用Object 类中的clone()方法。clone()方法可以用来完成对象的浅克隆。所谓浅克隆就是说被克隆的对象各个属性都是基本类型,而不是引用类型。如果存在引用类型的属性,则需要进行深克隆。下面对这两种克隆方式进行举例说明。
1.浅克隆(1)编写Address 类,首先在该类中定义state(表示国家)、province(表示省)和city(表示市)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,最后重写toString()方法方便输出该类的对象,代码如下:
1.浅克隆(1)编写Address 类,首先在该类中定义state(表示国家)、province(表示省)和city(表示市)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,最后重写toString()方法方便输出该类的对象,代码如下:
地址对象:
packagecom.nf147.Constroller;public class Address implementsCloneable {private String state; //国家
private String province; //省
private String city; //市
publicAddress() {
}publicAddress(String state, String province, String city) {this.state =state;this.province =province;this.city =city;
}publicString getState() {returnstate;
}public voidsetState(String state) {this.state =state;
}publicString getProvince() {returnprovince;
}public voidsetProvince(String province) {this.province =province;
}publicString getCity() {returncity;
}public voidsetCity(String city) {this.city =city;
}
@Overridepublic String toString() { //重写toString
StringBuilder sb=newStringBuilder();
sb.append("国家:"+state+",");
sb.append("省:"+province+",");
sb.append("市:"+city+",");returnsb.toString();
}
}
编写Employee 类,首先在该类中定义name(表示姓名)、age(表示年龄)和address(表示地址)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,再重写toString()方法方便输出该类的对象,最后重写clone()方法来提供克隆的功能,代码如下:
员工:
packagecom.nf147.Constroller;public class Employee implementsCloneable {private String name; //姓名
private int age; //年龄
private Address address; //地址
public Employee(String name, intage, Address address) {this.name =name;this.age =age;this.address =address;
}publicEmployee() {
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}publicAddress getAddress() {returnaddress;
}public voidsetAddress(Address address) {this.address =address;
}
@Overridepublic String toString() { //重新toString()方法
return "Employee{" +
"姓名='" + name + '\'' +
", 年龄=" + age +
", 地址=" + address +
'}';
}public Employee clone() { //实现浅克隆
Employee employee = null;try{
employee= (Employee) super.clone();
employee.address=address.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}returnemployee;
}
}
测试类:
packagecom.nf147.Constroller;public classTestClone {public static voidmain(String[] args) {
System.out.println("克隆之前:");
Address address= new Address("中国", "吉林", "长春");
Employee employee1= new Employee("无语", 32, address);
System.out.println("员工 1 的信息");
System.out.println(employee1);
System.out.println("====================");
System.out.println("克隆之后:");
Employee employee2=employee1.clone();
employee2.getAddress().setState("中国");
employee2.getAddress().setProvince("辽宁");
employee2.getAddress().setCity("大连");
employee2.setName("倾城");
employee2.setAge(33);
System.out.println("员工2 的 信息");
System.out.println(employee2);
System.out.println("员工1的 信息");
System.out.println(employee1);
}
}
截图:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CM5cTO2IDN5IDN0EmMzIDM4YTNxczM4IzNwkjY5YDOj9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
说明:
从图中可以看到,对于引用类型并没有克隆成功。
2.深克隆(1)编写类Address1,在该类中首先定义state(表示国家)、province(表示省)和city(表示市)3 个域,然后在构造方法中初始化这3 个域,并提供了getter()和setter()方法用于获得和修改这3 个域,再重写toString()方法方便输出该类的对象,最后重写clone()方法提供克隆的功能,关键代码如下:
packagecom.nf147.Constroller;public class Address implementsCloneable {private String state; //国家
private String province; //省
private String city; //市
publicAddress() {
}publicAddress(String state, String province, String city) {this.state =state;this.province =province;this.city =city;
}publicString getState() {returnstate;
}public voidsetState(String state) {this.state =state;
}publicString getProvince() {returnprovince;
}public voidsetProvince(String province) {this.province =province;
}publicString getCity() {returncity;
}public voidsetCity(String city) {this.city =city;
}
@Overridepublic String toString() { //重写toString
StringBuilder sb=newStringBuilder();
sb.append("国家:"+state+",");
sb.append("省:"+province+",");
sb.append("市:"+city+",");returnsb.toString();
}
@OverrideprotectedAddress clone(){
Address address= null;try{
address=(Address)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}returnaddress;
}
}
说明:
Address 类的域不是基本类型就是不可变类型,所以可以直接使用浅克隆。
(2)编写Employee类,首先在该类中定义name(表示姓名)、age(表示年龄)和address(表示地址)3 个域,然后在构造方法中初始化这3 个域,并提供getter()和setter()方法用于获得和修改这3 个域,再重写toString()方法方便输出该类的对象,最后重写clone()方法来提供克隆的功能。代码如下:
packagecom.nf147.Constroller;public class Employee implementsCloneable {private String name; //姓名
private int age; //年龄
private Address address; //地址
public Employee(String name, intage, Address address) {this.name =name;this.age =age;this.address =address;
}publicEmployee() {
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}publicAddress getAddress() {returnaddress;
}public voidsetAddress(Address address) {this.address =address;
}
@Overridepublic String toString() { //重新toString()方法
return "Employee{" +
"姓名='" + name + '\'' +
", 年龄=" + age +
", 地址=" + address +
'}';
}public Employee clone() { //实现浅克隆
Employee employee = null;try{
employee= (Employee) super.clone();
employee.address=address.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}returnemployee;
}
}
测试:
packagecom.nf147.Constroller;public classTestClone {public static voidmain(String[] args) {
System.out.println("克隆之前:");
Address address= new Address("中国", "吉林", "长春");
Employee employee1= new Employee("无语", 32, address);
System.out.println("员工 1 的信息");
System.out.println(employee1);
System.out.println("====================");
System.out.println("克隆之后:");
Employee employee2=employee1.clone();
employee2.getAddress().setState("中国");
employee2.getAddress().setProvince("辽宁");
employee2.getAddress().setCity("大连");
employee2.setName("倾城");
employee2.setAge(33);
System.out.println("员工2 的 信息");
System.out.println(employee2);
System.out.println("员工1的 信息");
System.out.println(employee1);
}
}
截图: