当前位置: 首页 > article >正文

《Java核心技术 卷I》对象克隆

对象克隆

讨论Cloneable接口,指示一个类提供了一个安全的clone方法。

对象引用建立副本,任何一个变量改变都会影响另一个变量。

如果希望copy一个新对象,初始状态相同,但之后它们各自会有自己不同的状态,这种情况可以使用clone方法。

如果数据域都是数值或其他基本类型,拷贝这些域没有任何问题,但是包含子对象的引用,拷贝域就会得到相同对象的另一个引用,这样一来,原对象和克隆对象仍然会共享一些信息。

以下这种克隆就是浅拷贝,并没有克隆出生日期对象。如果原对象与浅拷贝对象共享子对象不可变,那共享就是安全的。

不过,通常子对象都是可变的,必须重新定义clone方法来建立一个深拷贝,同时克隆出所有子对象。

    package corejava;

import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Objects;

public class EmployeeTest {

    public static void main(String[] args) throws CloneNotSupportedException {
        

        Employee e = new Employee("孙悟空", 75000,1987,12,15);
        Employee e1 = (Employee) e.clone();
        System.out.println(e==e1);
        System.out.println(e.equals(e1));
        System.out.println(e.hashCode()==e1.hashCode());
        System.out.println(e.getHireDay()==e1.getHireDay());
                //结果false,true,false,true,总结来说就是浅拷贝,出生日期不该是同一对象。      
    }

}
class Employee implements Comparable<Employee>,Cloneable {
    //实例字段
    private String name;
    private double salary;
    private Date hireDay;
    int percent = 10;
    //构造器
    public Employee(String n,double s,int year,int month, int day) {
        name = n;
        salary = s;
        GregorianCalendar calendar = new GregorianCalendar(year,month-1,day);
        hireDay = calendar.getTime();
    }
    public Employee() {}
    //
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public Date getHireDay() {
        return hireDay;
    }
    public void setHireDay(Date hireDay) {
        this.hireDay = hireDay;
    }
    public void raiseSalary(Employee e) {
        e.percent = 15;
        double raise = salary * e.percent /100;
        salary += raise;
    }
    @Override
    public boolean equals(Object otherObject) {
        super.equals(otherObject);
//        if(this==otherObject) return true;
        if(otherObject==null) return false;
        if(getClass()!=otherObject.getClass()) return false;
        Employee other = (Employee) otherObject;
        return this.name.equals(other.name)
                &&this.salary==other.salary
                &&Objects.equals(this.hireDay, other.hireDay);
    }
    @Override
    public int compareTo(Employee o) {
        return Double.compare(getSalary(), o.getSalary());
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        return super.clone();
    }
}

对于每一个类,需要确定:

  • 默认的clone方法是否满足要求。
  • 是否可以在可变的子对象上调用clone来修补默认的clone方法。
  • 是否不该使用clone。

实际上第3个选项是默认选项,如果选择第1项或第2项,类必须:

  • 实现Cloneable接口。
  • 重新定义clone方法,并指定public访问修饰符。

不实现接口,无法克隆,会报错,可以把克隆接口看成一个标识,当前类所实现的接口数组中包括克隆接口,那么虚拟机执行克隆动作。

注释:Cloneable接口是Java提供的一组标记接口(tagging interface)之一,也称为记号接口(marker interface)。它不包含任何方法,唯一作用就是允许类型查询中使用instanceof,建议你自己的程序中不要使用标记接口。

上面代码改为深拷贝的案例:

    //深拷贝
    public Employee clone() throws CloneNotSupportedException{
        Employee cloned = (Employee) super.clone();
        cloned.hireDay = (Date) hireDay.clone();
        return cloned;
    }

所有数组都有clone方法用来建立一个新数组。


http://www.kler.cn/a/383097.html

相关文章:

  • Unity中可以使用图片或mov的透明的shader
  • 使用ssh-key免密登录服务器或免密连接git代码仓库网站
  • 【物联网技术】ESP8266 WIFI模块在STA模式下作为TCP服务器与多个电脑/手机网络助手(TCP客户端)通信——TCP数据透传
  • 【Golang】sql.Null* 类型使用(处理空值和零值)
  • celery加速爬虫 使用flower 可视化地查看celery的实时监控情况
  • 应对传统能源企业管理人员青黄不接问题:搭建系统完善的招聘管理体系
  • LeetCode 热题100之图论
  • Hive 2.x 的安装与配置
  • GPU架构概述
  • python数据分析笔记
  • 如何选择适合TikTok创作者的高性价比专线网络:全方位指南
  • 【算法篇】--重温算法题
  • Pulsargeist:恐怖类型的 XR 大空间项目创新玩法
  • SQL练习专场--01
  • 【glm4-voice-9b 本地运行并测试 gradio+notebook】
  • 探索空间计算与 VR 设备的未来:4K4DGen 高分辨率全景 4D 内容生成系统
  • ssm061基于SSM框架的个人博客网站的设计与实现+vue(论文+源码)_kaic
  • AI 搜索来势汹汹,互联网将被颠覆还是进化?
  • Openlayers高级交互(20/20):超级数据聚合,页面不再混乱
  • 使用 Let’s Encrypt 获取免费SSL证书
  • 城镇住房保障系统:SpringBoot开发要点
  • TLU - Net:一种用于钢材表面缺陷自动检测的深度学习方法
  • c语言架构的一点构想
  • 挂钩图像分割安全状态与危险状态识别系统:更新创新流程
  • 推荐一款可视化和检查原始数据的工具:RawDigger
  • Midjourney从入门到精通教程,10分钟让你从小白变大神!【珍藏版】