纸上得来终觉浅
1.现在遇到了一个对象copy的问题,用Java的克隆可以解决,所以克隆解决的是对象拷贝一份;希望达到更改克隆的那一份的属性时,原来的对象不受影响;
2.克隆需要在类上继承一个接口,只不过默认情况下在clone时,只复制基本的数据类型(八个),对于属性是其他类型的情况,如果还想复制一份的话就要给属性所在的类同样继承一个接口,克隆包括下面的几个操作:
1)类前加上Cloneable接口;
2)重写其中的Clone方法(执行super.clone(),然后强转一下即可);
如果想给属性也克隆的话,加上下面步骤:
3)在super.clone()后,执行属性的克隆
3.具体示例如下:
package roadArchitectWeb.Test;
class mStudent{
private String name;
private String age;
public mStudent(String name, String age) {
super();
this.name = name;
this.age = age;
}
}
class tStudent implements Cloneable{
private String name;
private String age;
public tStudent(String name, String age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
protected tStudent clone(){
tStudent tStudent = null;
try {
tStudent = (tStudent)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return tStudent;
}
}
class Person implements Cloneable{
private String sex;
private tStudent tStudent;
private mStudent mStudent;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public tStudent gettStudent() {
return tStudent;
}
public void settStudent(tStudent tStudent) {
this.tStudent = tStudent;
}
public mStudent getmStudent() {
return mStudent;
}
public void setmStudent(mStudent mStudent) {
this.mStudent = mStudent;
}
public Person(String sex,tStudent tStudent,mStudent mStudent){
super();
this.sex = sex;
this.tStudent = tStudent;
this.mStudent = mStudent;
}
@Override
protected Person clone(){
Person person = null;
try {
person = (Person)super.clone();
person.tStudent = tStudent.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return person;
}
}
public class Test15 {
public static void main(String[] args) {
/*浅克隆对于基本类型属性的类*/
tStudent tStudent1 = new tStudent("Jintao_Ma", "23");
tStudent tStudent2 = tStudent1.clone();
/*浅克隆对于基本数据类型是复制一份,所以下面两者不等*/
System.out.println(tStudent1==tStudent2);
/*String不是基本类型,所以并没有复制,所以相等*/
System.out.println(tStudent1.getName() == tStudent2.getName());
/*浅克隆对于含有非基本类型属性的类*/
tStudent tStudent3 = new tStudent("zhangming2","26");
mStudent mStudent = new mStudent("lizheng2","24");
Person person1 = new Person("男", tStudent3, mStudent);
Person person2 = person1.clone();
/*下面两个应该是不同的*/
System.out.println(person1==person2);
/*tStudent由于克隆,应该也是不一样的*/
System.out.println(person1.gettStudent()==person2.gettStudent());
/*mStudent由于不克隆,应该是一样的*/
System.out.println(person1.getmStudent()==person2.getmStudent());
}
}
结果如下:
false
true
false
false
true
注: 注意到这样一个情况,
对于String(还有Integer等基本类型的封装类)类型不是基本数据类型,但是我们也没法加上Cloneable接口,这样的话得到的就是一个引用了,那么在对克隆对象进行操作的时候不是会影响到原来的值吗?
答案:不会,因为基本数据类型的封装类比较特殊,即使是引用但是当修改其中的一个值的时候,会新分配一块内存用来保存新的值,这个引用指向新的内存空间;所以在克隆的时候把这些基本数据类型的封装类当作基本的数据类型来看待,能够实现我们的目标,即"希望达到更改克隆的那一份的属性时,原来的对象不受影响";
4.对于Java的克隆效果,还有一种实现就是把类序列化,通过流保存下来
之前学习I/O流的时候,准备以后做一个深入I/O的总结,这种方法就是其中之一。后面再说