一.Cloneable 的用途
Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。
二.克隆的分类
(1)浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。
(2)深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。
三.克隆的举例
要让一个对象进行克隆,其实就是两个步骤:
1. 让该类实现java.lang.Cloneable接口;
2. 重写(override)Object类的clone()方法。
四.浅克隆的举例
五.深克隆的举例
如果要深克隆,需要重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法; 注意如下代码的clone()方法
但是也有不足之处,如果Husband内有N个对象属性,突然改变了类的结构,还要重新修改clone()方法。解决办法:可以使用Serializable运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。
二.克隆的分类
(1)浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。
(2)深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。
三.克隆的举例
要让一个对象进行克隆,其实就是两个步骤:
1. 让该类实现java.lang.Cloneable接口;
2. 重写(override)Object类的clone()方法。
- public class Wife implements Cloneable {
- private int id;
- private String name;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Wife(int id,String name) {
- this.id = id;
- this.name = name;
- }
- @Override
- public int hashCode() {//myeclipse自动生成的
- final int prime = 31;
- int result = 1;
- result = prime * result + id;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- return result;
- }
- @Override
- public boolean equals(Object obj) {//myeclipse自动生成的
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Wife other = (Wife) obj;
- if (id != other.id)
- return false;
- if (name == null) {
- if (other.name != null)
- return false;
- } else if (!name.equals(other.name))
- return false;
- return true;
- }
- @Override
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- /**
- * @param args
- * @throws CloneNotSupportedException
- */
- public static void main(String[] args) throws CloneNotSupportedException {
- Wife wife = new Wife(1,"wang");
- Wife wife2 = null;
- wife2 = (Wife) wife.clone();
- System.out.println("class same="+(wife.getClass()==wife2.getClass()));//true
- System.out.println("object same="+(wife==wife2));//false
- System.out.println("object equals="+(wife.equals(wife2)));//true
- }
- }
四.浅克隆的举例
- public class Husband implements Cloneable {
- private int id;
- private Wife wife;
- public Wife getWife() {
- return wife;
- }
- public void setWife(Wife wife) {
- this.wife = wife;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public Husband(int id) {
- this.id = id;
- }
- @Override
- public int hashCode() {//myeclipse自动生成的
- final int prime = 31;
- int result = 1;
- result = prime * result + id;
- return result;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- @Override
- public boolean equals(Object obj) {//myeclipse自动生成的
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Husband other = (Husband) obj;
- if (id != other.id)
- return false;
- return true;
- }
- /**
- * @param args
- * @throws CloneNotSupportedException
- */
- public static void main(String[] args) throws CloneNotSupportedException {
- Wife wife = new Wife(1,"jin");
- Husband husband = new Husband(1);
- Husband husband2 = null;
- husband.setWife(wife);
- husband2 = (Husband) husband.clone();
- System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true
- System.out.println("husband object same="+(husband==husband2));//false
- System.out.println("husband object equals="+(husband.equals(husband)));//true
- System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true
- System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//true
- System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true
- }
- }
五.深克隆的举例
如果要深克隆,需要重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法; 注意如下代码的clone()方法
- public class Husband implements Cloneable {
- private int id;
- private Wife wife;
- public Wife getWife() {
- return wife;
- }
- public void setWife(Wife wife) {
- this.wife = wife;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public Husband(int id) {
- this.id = id;
- }
- @Override
- public int hashCode() {//myeclipse自动生成的
- final int prime = 31;
- int result = 1;
- result = prime * result + id;
- return result;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Husband husband = (Husband) super.clone();
- husband.wife = (Wife) husband.getWife().clone();
- return husband;
- }
- @Override
- public boolean equals(Object obj) {//myeclipse自动生成的
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Husband other = (Husband) obj;
- if (id != other.id)
- return false;
- return true;
- }
- /**
- * @param args
- * @throws CloneNotSupportedException
- */
- public static void main(String[] args) throws CloneNotSupportedException {
- Wife wife = new Wife(1,"jin");
- Husband husband = new Husband(1);
- Husband husband2 = null;
- husband.setWife(wife);
- husband2 = (Husband) husband.clone();
- System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true
- System.out.println("husband object same="+(husband==husband2));//false
- System.out.println("husband object equals="+(husband.equals(husband)));//true
- System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true
- System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//false
- System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true
- }
- }
但是也有不足之处,如果Husband内有N个对象属性,突然改变了类的结构,还要重新修改clone()方法。解决办法:可以使用Serializable运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。