答:有两种方式:(第三种可不答)
public class Employee implements Cloneable{
private String name;
private int age;
private Person person;
}
public class Person {
private String name;
private int age;
private int sex;
//下面省略构造器,get set toString方法
}
public class Employee implements Cloneable{
private String name;
private int age;
private Person person;
public Employee() {
}
public Employee(String name, int age, Person person) {
this.name = name;
this.age = age;
this.person = person;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
//下面省略get set toString方法
}
Person person = new Person("name",10,1);
Employee employee = new Employee("fanglei",20,person);
System.out.println("employee: "+employee);
try {
//浅克隆
Employee employee1 = (Employee) employee.clone();
System.out.println("employee1: "+ employee1);
//修改employee中person的属性,employee1中的属性也修改了
employee.getPerson().setAge(100);
System.out.println("employee: "+employee);
System.out.println("employee1: "+ employee1);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
下图为修改之后的Person类:其实就是实现Clonable接口并且重写clone方法
public class Person implements Cloneable{
private String name;
private int age;
private int sex;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
下图为Employee类clone方法修改之后:
@Override
public Object clone() throws CloneNotSupportedException {
Employee employee = null;
employee = (Employee) super.clone();
employee.person = (Person) this.person.clone();
return employee;
}
再调用刚刚的测试克隆代码:
Person person = new Person("name",10,1);
Employee employee = new Employee("fanglei",20,person);
System.out.println("employee: "+employee);
try {
//浅克隆
Employee employee1 = (Employee) employee.clone();
System.out.println("employee1: "+ employee1);
//修改employee中person的属性,employee1中的属性也修改了
employee.getPerson().setAge(100);
System.out.println("employee: "+employee);
System.out.println("employee1: "+ employee1);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
public class Employee implements Serializable{
}
public class Person implements Serializable{
}
public class CloneUtil {
private CloneUtil() {
throw new AssertionError();
}
/**
* Clone.
* 调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义,
* 这两个基于内存的流只要垃圾回收器清理对象时就能够释放资源,这一点不同于对外部资源(如文件流)的释放。
*
* @param obj The object.
* @param The type.
* @return The cloned object.
* @throws Exception The exception.
*/
public static <T> T clone(T obj) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(obj);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (T) objectInputStream.readObject();
}
}
Person p1 = new Person("name",10,1);
Employee e1 = new Employee("fanglei",20,p1);
System.out.println("e1: "+e1);
try {
Employee e2 = CloneUtil.clone(e1);
System.out.println("e2: "+ e2);
e1.getPerson().setAge(100);
System.out.println("e1: "+e1);
System.out.println("e2: "+ e2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
try {
Student stu1 = new Student();
stu1.setNumber(12345);
Student stu2 = new Student();
BeanUtils.copyProperties(stu2, stu1);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
try {
Student stu1 = new Student();
stu1.setNumber(12345);
Student stu2 = new Student();
PropertyUtils.copyProperties(stu2, stu1);
catch (NoSuchMethodException e) {
e.printStackTrace();
}