java 克隆

Java 克隆分为浅克隆和深克隆

浅克隆:

       将原型的所有属性的值复制到新对象,新对象基本数据类型的字段值的改变不会影响到被复制对象,而引用类型复制的是指向堆的引用地址,所以新对象和被复制对象的引用类型指的是同一个地址,任意一个改变,都会受印象

     

 public class InfomationType implements Cloneable{
    @SerializedName("TYPEID")
    private String typeId;//类型ID
    @SerializedName("TYPENAME")
    public String typeName;//类型名称
    @SerializedName("TIMES")
    private String times;//显示时间段
    @SerializedName("PARENTID")
    private String parentId;//父ID

   public XgMessageInfo xgMessageInfo;

    public XgMessageInfo getXgMessageInfo() {
        return xgMessageInfo;
    }

    public void setXgMessageInfo(XgMessageInfo xgMessageInfo) {
        this.xgMessageInfo = xgMessageInfo;
    }

    public String getTypeId() {
        return typeId;
    }

    public void setTypeId(String typeId) {
        this.typeId = typeId;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    public String getTimes() {
        return times;
    }

    public void setTimes(String times) {
        this.times = times;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }



    @Override
    public Object clone() throws CloneNotSupportedException {
           InfomationType  infomationType=null;
    try{
        infomationType=(InfomationType)super.clone();
    //    infomationType.xgMessageInfo=(XgMessageInfo)xgMessageInfo.clone();
        return infomationType;
    }catch (Exception e){

    }
    return null;
}
    }
}
public class XgMessageInfo implements Serializable {
    private String id;
    private String createTime;
    private String createUser;
    private String createUserName;
    public String infoTitle;
    private String type;
    private String tenantId;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public String getCreateUser() {
        return createUser;
    }

    public void setCreateUser(String createUser) {
        this.createUser = createUser;
    }

    public String getCreateUserName() {
        return createUserName;
    }

    public void setCreateUserName(String createUserName) {
        this.createUserName = createUserName;
    }

    public String getInfoTitle() {
        return infoTitle;
    }

    public void setInfoTitle(String infoTitle) {
        this.infoTitle = infoTitle;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getTenantId() {
        return tenantId;
    }

    public void setTenantId(String tenantId) {
        this.tenantId = tenantId;
    }
}
InfomationType infomationiType  =new InfomationType();
XgMessageInfo xgMessageInfo=new XgMessageInfo();
infomationiType.setXgMessageInfo(xgMessageInfo);
infomationiType.setTypeName("留言信息");
try {
    InfomationType infomationiTypeClone=(InfomationType)infomationiType.clone();
    Log.d("infoTypeClone",infomationiType.toString());
    Log.d("infoTypeClone","clone="+infomationiTypeClone.toString());
    Log.d("infoTypeClone",infomationiType.typeName.toString());
    Log.d("infoTypeClone","clone="+infomationiTypeClone.typeName.toString());
    Log.d("infoTypeClone",infomationiType.xgMessageInfo.toString());
    Log.d("infoTypeClone","clone="+infomationiTypeClone.xgMessageInfo.toString());
    结果:
     **********.InfomationType@41b17010
     **********.InfomationType@41b17298
     留言信息
     clone=留言信息
     **********.XgMessageInfo@41b17230
     **********.XgMessageInfo@41b17230


 
    infomationiTypeClone.setTypeName("资讯信息");
    infomationiTypeClone.getXgMessageInfo().setInfoTitle("某某同学....你有一条留言信息");
    Log.d("infoTypeClone",infomationiType.typeName.toString());
    Log.d("infoTypeClone","clone="+infomationiTypeClone.typeName.toString());
    Log.d("infoTypeClone",infomationiType.getXgMessageInfo().getInfoTitle());
    Log.d("infoTypeClone","clone="+infomationiTypeClone.getXgMessageInfo().getInfoTitle());
    结果:
     留言信息
     clone=资讯信息
    某某同学....你有一条留言信息
    clone=某某同学....你有一条留言信息
} catch (CloneNotSupportedException e) {
    e.printStackTrace();
}

深克隆:

       将原型的所有属性的值复制到新对象,新对象基本数据类型的字段值的改变不会影响到被复制对象,引用类型复制的不是指向堆的引用地址,而是引用的对象,所以原型和深克隆的对象的引用类型指向的是堆上不同的对象。所以克隆对象的引用类型的改变不会影响到与原型的引用类型。

操作:将InfomationType的克隆方法里添加 infomationType.xgMessageInfo=(XgMessageInfo)xgMessageInfo.clone();这句代码

 @Override
    public Object clone() throws CloneNotSupportedException {
            InfomationType  infomationType=null;
            try{
                infomationType=(InfomationType)super.clone();
                infomationType.xgMessageInfo=(XgMessageInfo)xgMessageInfo.clone();
                return infomationType;
            }catch (Exception e){

            }
            return null;
        }
}
InfomationType infomationiType  =new InfomationType();
    XgMessageInfo xgMessageInfo=new XgMessageInfo();
    infomationiType.setXgMessageInfo(xgMessageInfo);
    infomationiType.setTypeName("留言信息");
    try {
        InfomationType infomationiTypeClone=(InfomationType)infomationiType.clone();
        //Log.d("xgMessageInfoClone",xgMessageInfo.getInfoTitle());
        // Log.d("xgMessageInfoClone","clone="+xgMessageInfoClone.getInfoTitle());
        Log.d("infoTypeClone",infomationiType.toString());
        Log.d("infoTypeClone","clone="+infomationiTypeClone.toString());
        Log.d("infoTypeClone",infomationiType.typeName.toString());
        Log.d("infoTypeClone","clone="+infomationiTypeClone.typeName.toString());
        Log.d("infoTypeClone",infomationiType.xgMessageInfo.toString());
        Log.d("infoTypeClone","clone="+infomationiTypeClone.xgMessageInfo.toString());
        结果:
        **********.InfomationType@18f05097       **********.InfomationType@2aa8284
      留言信息
      clone=留言信息
      **********.XgMessageInfo@c75fa6d  //不同的对象
      **********.XgMessageInfo@1dd706a2
        infomationiTypeClone.setTypeName("资讯信息");
        infomationiTypeClone.getXgMessageInfo().setInfoTitle("某某同学....你有一条留言信息");
        Log.d("infoTypeClone",infomationiType.typeName.toString());
        Log.d("infoTypeClone","clone="+infomationiTypeClone.typeName.toString());
        Log.d("infoTypeClone",infomationiType.getXgMessageInfo().getInfoTitle()+",");
        Log.d("infoTypeClone","clone="+infomationiTypeClone.getXgMessageInfo().getInfoTitle()+",");
        //  Log.d("xgMessageInfoClone",xgMessageInfo.getInfoTitle());
        //   Log.d("xgMessageInfoClone","clone="+xgMessageInfoClone.getInfoTitle());
       结果:
       留言信息
       clone=资讯信息
       null,          //克隆对象的引用属性的改变不会影响到原型的对象的引用属性
       clone=某某同学....你有一条留言信息,


    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
}

利用serializable实现深克隆

类要实现Serializable接口 public class InfomationType implements Cloneable,Serializable,要不然会报java.io.NotSerializableException: matcheng.app.pad.datebean.InfomationType错误。

在InfomationType类里添加深克隆方法
public Object DeepClone(){
    try {
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(this);
        ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois=new ObjectInputStream(bis);
        Object o=ois.readObject();;
        return o;
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}
 InfomationType infomationiType  =new InfomationType();
    XgMessageInfo xgMessageInfo=new XgMessageInfo();
    infomationiType.setXgMessageInfo(xgMessageInfo);
    infomationiType.setTypeName("留言信息");
    try {
       // InfomationType infomationiTypeClone=(InfomationType)infomationiType.clone();
       //利用Serializable实现深克隆
        InfomationType infomationiTypeClone=(InfomationType)infomationiType.DeepClone();
        //Log.d("xgMessageInfoClone",xgMessageInfo.getInfoTitle());
        // Log.d("xgMessageInfoClone","clone="+xgMessageInfoClone.getInfoTitle());
        Log.d("infoTypeClone",infomationiType.toString());
        Log.d("infoTypeClone","clone="+infomationiTypeClone.toString());
        Log.d("infoTypeClone",infomationiType.typeName.toString());
        Log.d("infoTypeClone","clone="+infomationiTypeClone.typeName.toString());
        Log.d("infoTypeClone",infomationiType.xgMessageInfo.toString());
        Log.d("infoTypeClone","clone="+infomationiTypeClone.xgMessageInfo.toString());
        结果:
       **********.InfomationType@2aa8284      **********.InfomationType@3282784e
     留言信息
     clone=留言信息
    **********.XgMessageInfo@10708d87 //XgMessageInfo类实现serializable接口,能实现深克隆
    **********.XgMessageInfo@1c892d6f
                  
  

      infomationiTypeClone.setTypeName("资讯信息");
      infomationiTypeClone.getXgMessageInfo().setInfoTitle("某某同学....你有一条留言信息");
      Log.d("infoTypeClone",infomationiType.typeName.toString());
      Log.d("infoTypeClone","clone="+infomationiTypeClone.typeName.toString());
      Log.d("infoTypeClone",infomationiType.getXgMessageInfo().getInfoTitle()+",");
      Log.d("infoTypeClone","clone="+infomationiTypeClone.getXgMessageInfo().getInfoTitle()+",");
     //  Log.d("xgMessageInfoClone",xgMessageInfo.getInfoTitle());
     //   Log.d("xgMessageInfoClone","clone="+xgMessageInfoClone.getInfoTitle());
    结果:
    留言信息
    clone=资讯信息
    null, //克隆对象的引用属性的改变不会影响到原型的对象的引用属性
    clone=某某同学....你有一条留言信息,


    } catch (Exception e) {
        e.printStackTrace();
    }
}

 

### Java 中的对象克隆Java中,对象克隆指的是创建一个新对象,该对象的状态与现有对象完全相同。为了实现这一目标,通常有两种方式:浅拷贝和深拷贝。 #### 实现 Cloneable 接口并重写 `clone()` 方法 要使某个类支持克隆操作,需让其继承`Cloneable`接口,并覆写来自`Object`类的受保护方法`clone()`。需要注意的是,由于`clone()`默认为`protected`级别,所以在子类中重新定义时应调整访问权限以便外部能够调用此函数[^4]。 对于实现了`Cloneable`接口的类而言,当调用它的实例上的`clone()`方法时,默认行为会执行字段级别的复制,这即是所谓的浅拷贝。在这种模式下,基本数据类型的成员会被直接赋值给新的对象;而对于引用类型,则只是简单地把原对象内部持有的引用地址传递过去,两个对象实际上指向同一内存位置的数据结构[^1]。 ```java public class Person implements Cloneable { private String name; private Address address; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } ``` 上述代码展示了最基础形式下的克隆机制,但它仅适用于不需要处理复杂嵌套关系的情况。如果希望得到独立于源对象之外的新副本(即深拷贝),则需要进一步定制化逻辑: - 对于不可变对象或基本数据类型组成的属性可以直接沿用父类提供的`super.clone()`; - 针对可变组件如数组、集合以及自定义实体类等,则应当单独为其分配空间并通过适当手段完成初始化工作,比如再次调用各自的`clone()`或是构造器来构建全新个体[^3]。 另一种常见的做法是利用序列化技术达成深层次的复制效果。具体来讲就是先将待仿制的目标转换成字节流保存起来,再读取这些二进制信息重建出另一个同等规格的事物出来。这种方式的优势在于无需关心内部细节就能获得彻底分离的结果,不过代价可能是性能开销较大而且依赖特定环境配置[^5]。 ```java import java.io.*; public class DeepCloneableObject implements Serializable { public static T deepCopy(T obj) throws IOException, ClassNotFoundException { // 序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(obj); // 反序列化 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bis); return (T)in.readObject(); } } ``` 以上介绍了两种主流途径用于解决Java里头的对象复制难题,开发者可以根据实际需求选取合适方案加以应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值