先用一个例子来说明假克隆吧,也就是用“=”之后的效果、。
public class Employee{
public Employee(){
}
public Employee(String name, int age){
this.age = age;
this.name = name;
}
@Override
public String toString(){
return "姓名: " + name + "年龄: " + age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public static void main(String[] args){
Employee demo1 = new Employee("rollen", 20);
System.out.println(demo1);
Employee demo2 = demo1;
demo2.setAge(100);
demo2.setName("hello world");
System.out.println(demo1);
System.out.println(demo2);
}
private String name;
private int age;
}
【运行结果】:
【运行结果】
姓名:rollen年龄:20
姓名:hello world年龄:100
姓名:hello world年龄:100
下面看看java中的浅拷贝
对于类中的每个域,如果只包含基本类型或者不可变的引用类型,如String,或者对象在其生命周期内不会发生变化,则可以使用浅拷贝来复制对象,但是一般使用深拷贝。
class Address{
public Address(){
}
public Address(String state, int number){
this.number = number;
this.state = state;
}
@Override
public String toString(){
return "state: " + state + " munber: " + number;
}
public String getState(){
return state;
}
public void setState(String state){
this.state = state;
}
public int getNumber(){
return number;
}
public void setNumber(int number){
this.number = number;
}
private String state;
private int number;
}
public class Employee implements Cloneable{
public Employee(){
}
public Employee(String name, int age, Address address){
this.address = address;
this.age = age;
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public Address getAddress(){
return address;
}
public void setAddress(Address address){
this.address = address;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("name:" + name + ", ");
sb.append("age:" + age + " \n");
sb.append("Address: " + address);
return sb.toString();
}
@Override
protected Employee clone(){
Employee employee = null;
try{
employee = (Employee) super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return employee;
}
public static void main(String[] args){
System.out.println("克隆之前:");
Address add1 = new Address("中国", 1);
Employee emp1 = new Employee("rollen", 20, add1);
System.out.println(emp1);
System.out.println("克隆之后");
Employee emp2 = emp1.clone();
emp2.setName("hello world");
emp2.setAge(100);
emp2.address.setNumber(2);
emp2.address.setState("美国");
System.out.println(emp1);
System.out.println("-----");
System.out.println(emp2);
}
private String name;
private int age;
private Address address;
}
【运行结果】:
克隆之前:
name:rollen, age:20
Address: state:中国munber: 1
克隆之后
name:rollen, age:20
Address: state:美国munber: 2
-----
name:hello world, age:100
Address: state:美国munber: 2
但是上面的主函数中的:
// emp2.address.setNumber(2);
// emp2.address.setState("美国");
替换为:
emp2.setAddress(new Address("美国", 2));
运行结果为:
克隆之前:
name:rollen, age:20
Address: number: 1state中国
克隆之后
name:rollen, age:20
Address: number: 1state中国
-----
name:hello world, age:100
Address: number: 2state美国
这里我有点不明白了,为什么这种情况下克隆之后两个address会不一样呢?
谁帮忙指点一下,谢谢了、
现在看看java对象的深克隆
class Address implements Cloneable{
public Address(){
}
public Address(String state, int number){
this.number = number;
this.state = state;
}
@Override
public String toString(){
return "state: " + state + " munber: " + number;
}
@Override
protected Address clone() throws CloneNotSupportedException{
Address address = null;
address = (Address) super.clone();
return address;
}
public String getState(){
return state;
}
public void setState(String state){
this.state = state;
}
public int getNumber(){
return number;
}
public void setNumber(int number){
this.number = number;
}
private String state;
private int number;
}
public class Employee implements Cloneable{
public Employee(){
}
public Employee(String name, int age, Address address){
this.address = address;
this.age = age;
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public Address getAddress(){
return address;
}
public void setAddress(Address address){
this.address = address;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("name:" + name + ", ");
sb.append("age:" + age + " \n");
sb.append("Address: " + address);
return sb.toString();
}
@Override
protected Employee clone(){
Employee employee = null;
try{
employee = (Employee) super.clone();
employee.address = address.clone();}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return employee;
}
public static void main(String[] args){
System.out.println("克隆之前:");
Address add1 = new Address("中国", 1);
Employee emp1 = new Employee("rollen", 20, add1);
System.out.println(emp1);
System.out.println("克隆之后");
Employee emp2 = emp1.clone();
emp2.setName("hello world");
emp2.setAge(100);
emp2.setAddress(new Address("美国", 2));
System.out.println(emp1);
System.out.println("-----");
System.out.println(emp2);
}
private String name;
private int age;
private Address address;
}
【运行结果】:
【运行结果】:
克隆之前:
name:rollen, age:20
Address: state:中国munber: 1
克隆之后
name:rollen, age:20
Address: state:中国munber: 1
-----
name:hello world, age:100
Address: state:美国munber: 2
序列化接口和对象克隆
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Address implements Serializable{
public Address(){
}
public Address(String state, int number){
this.number = number;
this.state = state;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("number: " + number);
sb.append("state" + state + "\n");
return sb.toString();
}
public String getState(){
return state;
}
public void setState(String state){
this.state = state;
}
public int getNumber(){
return number;
}
public void setNumber(int number){
this.number = number;
}
private String state;
private int number;
}
public class Employee implements Cloneable, Serializable{
public Employee(){
}
public Employee(String name, int age, Address address){
this.address = address;
this.age = age;
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public Address getAddress(){
return address;
}
public void setAddress(Address address){
this.address = address;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("name:" + name + ", ");
sb.append("age:" + age + " \n");
sb.append("Address: " + address);
return sb.toString();
}
@Override
protected Employee clone(){
Employee employee = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try{
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
employee = (Employee) ois.readObject();
ois.close();
}catch(Exception e){
e.printStackTrace();
}
return employee;
}
public static void main(String[] args){
System.out.println("克隆之前:");
Address add1 = new Address("中国", 1);
Employee emp1 = new Employee("rollen", 20, add1);
System.out.println(emp1);
System.out.println("克隆之后");
Employee emp2 = emp1.clone();
emp2.setName("hello world");
emp2.setAge(100);
emp2.address.setNumber(2);
emp2.address.setState("美国");
System.out.println(emp1);
System.out.println("-----");
System.out.println(emp2);
}
private String name;
private int age;
private Address address;
}
【运行结果】:
克隆之前:
name:rollen, age:20
Address: number: 1state中国
克隆之后
name:rollen, age:20
Address: number: 1state中国
-----
name:hello world, age:100
Address: number: 2state美国
对于任何一个序列化的对象,都必须要求实现Serializable接口。其次,如果这个类的域中也有引用对象,则也有要求这个引用类型也实现这个接口,。最后,序列化方式实现克隆效率不高,没有直接深度克隆的效率高。有兴趣的朋友可以测试一下。