java cloneable 接口_Cloneable 接口 记号接口(标记接口)「建议收藏」

java cloneable 接口_Cloneable 接口 记号接口(标记接口)「建议收藏」Cloneable接口指示了一个类提供了一个安全的clone方法。首先了解Object.clone()方法:clone是Object超类的一个protected方法,用户代码不能直接调用这个方法。Object的子类只能调用Object超类中受保护的clone方法来克隆它自己的对象,必须重新定义clone为public才能允许所有方法调用这个类的实例的clone方法克隆对象。clone方法的作用:…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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

首先了解Object.clone()方法:

clone是Object超类的一个protected方法,用户代码不能直接调用这个方法。Object的子类只能调用Object超类中受保护的clone方法来克隆它自己的对象,必须重新定义clone为public才能允许所有方法调用这个类的实例的clone方法克隆对象。

clone方法的作用:clone方法对Employee调用它对这个对象一无所知,所以只能逐个域地进行拷贝。a. 如果对象中的所有数据域都是数值或者其他基本类型,拷贝这些域没有问题;b. 但是如果对象中包含子对象的引用,拷贝域就会得到相同子对象的另一个引用(浅拷贝)。这样一来,原对象和克隆的对象仍然会共享一些信息。

浅拷贝的影响:如果原对象和浅克隆对象共享的子对象是不可变的,那么这种共享就是安全的。如果子对象属于一个不可变的类,如String,就是这种情况。或者在对象的生命周期中,子对象一直包含不变的常量,没有更改器会改变它,就是没有方法会生成它的引用,这种情况同样是安全的(举个栗子:下面例子中hiereDay是一个Date对象,Date类的域是可变的,所以hireDay需要深拷贝。而LocalDate的域不可变,如果hireDay是不可变的LocaDate类的一个实例,就无需我们做任何处理了)。

public class Employee implements Cloneable {

private String name;

private double salary;

private Date hireDay;

public Employee(String name, double salary)

{

this.name = name;

this.salary = salary;

hireDay = new Date();

}

@Override

public Employee clone() throws CloneNotSupportedException

{

// call Object.clone() Employee cloned = (Employee) super.clone(); // clone会逐个域的进行拷贝

// clone mutable fields cloned.hireDay = (Date) hireDay.clone();

return cloned;

}

public void setHireDay(int year, int month, int day)

{

Date newHireDay = new GregorianCalendar(year, month – 1, day).getTime();

// Example of instance field mutation hireDay.setTime(newHireDay.getTime());

}

public void raiseSalary(double byPercent)

{

double raise = salary * byPercent / 100;

salary += raise;

}

public String toString()

{

return “Employee[name=” + name + “,salary=” + salary + “,hireDay=” + hireDay + “]”;

}

}

public class Main {

public static void main(String[] args)

{

Employee employee = new Employee(“jack1”, 20000);

try {

Employee clone = employee.clone();

employee.raiseSalary(20);

employee.setHireDay(2020, 10, 22);

System.out.println(employee.toString());

System.out.println(clone.toString());

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

}

}

/*** 输出:Employee[name=jack1,salary=24000.0,hireDay=Thu Oct 22 00:00:00 CST 2020]Employee[name=jack1,salary=20000.0,hireDay=Sun Oct 13 17:47:26 CST 2019]*/

再看一个栗子,hireDay为不可变LocalDate类的实例时(private LocalDate hireDay;),Main.java类代码基本不变(构造函数有改变 -> Employee employee =newEmployee(“jack1”,20000,2019,10,13);):

public class Employee implements Cloneable {

private String name;

private double salary;

private LocalDate hireDay;

public Employee(String name, double salary, int year, int month, int day)

{

this.name = name;

this.salary = salary;

hireDay = LocalDate.of(year, month, day);

}

@Override

public Employee clone() throws CloneNotSupportedException

{

// call Object.clone() Employee cloned = (Employee) super.clone();

// // clone mutable fields// cloned.hireDay = (Date) hireDay.clone();

return cloned;

}

public void setHireDay(int year, int month, int day)

{

// Date newHireDay = new GregorianCalendar(year, month – 1, day).getTime();// // Example of instance field mutation// hireDay.setTime(newHireDay.getTime()); hireDay = LocalDate.of(year, month, day);

}

public void raiseSalary(double byPercent)

{

double raise = salary * byPercent / 100;

salary += raise;

}

public String toString()

{

return “Employee[name=” + name + “,salary=” + salary + “,hireDay=” + hireDay + “]”;

}

}

对于一个要实现clone方法的类,需要确定:实现Cloneable接口;

重新定义clone方法,并且制定public访问修饰符。

注意:

Cloneable接口的出现与接口的正常实现没有关系。具体讲,它(Cloneable接口)没有指定clone方法,这个方法是从Object类继承的(应该是实现接口的类从Object类继承)。Cloneable接口的作用只是作为一个标记,指示 类设计者 了解克隆过程。对象对于克隆很“偏执”,如果一个对象请求克隆,但没有实现这个接口,就会生成一个受查异常(报错:java.lang.CloneNotSupportedException)。

Cloneable接口是Java提供的一组标记接口(tagging interface)之一。有些程序员也称之为记号接口(marker interface)。注意:Comparable等接口的通常用途是确保一个类实现一个或一组特定的方法。标记接口不包含任何方法,它唯一的作用就是允许在类型查询中使用instanceof:

if (obj instanceof Cloneable) ..

建议自己程序中不要使用标记接口。

即使clone的默认(浅拷贝)实现能够满足要求,还是需要实现Cloneable接口,将clone方法重新定义为public,再调用super.clone()。

class Employee implements Cloneable()

{

// raise visibility level to public, change return type public Employee clone() throws CloneNotSupportedException

{

return (Employee) super.clone();

}

}

如果一个类重写了clone方法,但是类没有声明实现接口 implements Cloneable,类会抛出一个CloneNotSupportedException异常。当然,Employee和Date类实现了Cloneable接口,所以不会抛出这个异常。不过编译器不会了解这一点,所以我们声明了这个异常:

public Employee clone() throws CloneNotSupportedException

这样,子类在不支持克隆时选择抛出一个CloneNotSupportedException异常。

clone没有想象中的那么常用,标准库中只有5%的类实现了clone。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/184369.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java轻量级web框架_什么是框架

    java轻量级web框架_什么是框架JEMSF框架前言今天我们准备向广大开发人员推荐一种新的框架,暂时取名JEMSF,如果您已经对Struts、Tapestry以及Spring和Hibernat有一些了解,那么应该可以更好的理解下面的文章,JEMSF是我在工作生涯中最大的一个创造,经历了很多考验和应用的试验,最后形成JEMSF。序一种新的事物的诞生需要经历很多的考验,我自认为JEMSF是一个很好的WEB应用框架,很久以前(2…

    2025年9月30日
    2
  • word在试图打开文件时遇到错误,检查稳定或驱动器文件权限

    word在试图打开文件时遇到错误,检查稳定或驱动器文件权限查网上说属性—解除锁定,就好了我看很多人也是这问题,这种方案就可以解决。但我的是根本就没有“解除锁定”这一选项。我用的是2013版的word,但可以用office2010打开(我电脑上安装了两个office版本)。而且在其它电脑上office2013可以打开。我的解决方案是用office2010打开后把昨天写的部分删除,发现用office2013可以打开了。然后再从201…

    2022年5月10日
    99
  • 【电赛】2017年电赛A题——三相逆变电源EG8030测试

    【电赛】2017年电赛A题——三相逆变电源EG8030测试目录:一、相关介绍1.创建窗口【Tk】2.创建标签【Label】3.创建按钮【Button】二、简易滚动抽奖界面代码三、界面展示注:本文仅用于学习交流分享,[若有不妥之处,请指正,感谢]关键词:【电赛】【三项逆变电源】【EG8030】用到的工具有:AltiumDesigner16.0实现的功能有:①实现三相SPWM②实现三相交流电一、相关介绍SPWM:脉冲宽度按正…

    2022年5月5日
    116
  • touchstart,touchmove,touchend触摸事件的小小实践心得

    近段时间使用html5开发一个公司内部应用,而触摸事件必然是移动应用中所必须的,刚开始以为移动设备上或许也会支持鼠标事件,原来是不支持的,好在webkit内核的移动浏览器支持touch事件,并且打包成

    2021年12月27日
    42
  • linux修改文件没有权限设置,Linux下修改文件权限(所有权)

    linux修改文件没有权限设置,Linux下修改文件权限(所有权)Linux与Unix是多用户操作系统,所以文件的权限与所有权的实现就显得很有必要;每个文件主要与三组权限打交道,分别是用户(user),用户组(group),其他用户(other)用户(u)是文件的所有者,通常有所有的文件的操作权限用户组(g)是多个用户的集合,可能有文件的部分访问权,相当于各用户之间的共享文件其他(o)是指文件所有者和用户组成员之外的任何人使用ls-l可以显示出当前目录下的文件…

    2025年10月31日
    4
  • 通达信常用颜色及图标「建议收藏」

    通达信常用颜色及图标「建议收藏」颜色代码大全:1)COLOR自定义色格式为COLOR+“RRGGBB”:RR、GG、BB表示红蓝色、绿色和蓝色的分量,每种颜色的取值范围是00-FF,采用了16进制)例如:MA5:MA(CLOS

    2022年8月1日
    21

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号