java 核心技术卷一笔记 6 .2.3 接口 lambda 表达式 内部类
6.2.3 对象克隆
Cloneable 接口,这个接口指示一个类提供了一个安全的clone方法。(稍作了解)
为一个对象引用的变量建立副本时,原变量和副本都是同一个对象的引用,任何一个变量改变都会影响另一个变量。
Employee original =new Employee("John Public",50000);
Employee copy=original;
copy.raiseSalary(10);//(加工资的一个方法)
如果希望copy是一个新对象,它的初始状态与original相同,但是以后它们会有自己不同的状态,这种情况下就可以使用clone方法。
Employee copy =original.clone();
copy.raiseSalary(10);(original没有改变)
对于一个类,需要确定:
1)默认的clone方法是否满足要求;
2)是否可以在可变的子对象上调用clone来修补默认的clone方法;
3)是否不该使用clone。(默认选项)
如果选择了第一项或第二项,类必须:
1)实现Cloneable接口;
2)重新定义clone方法,并指定public访问修饰符。
Cloneable接口是java提供的一组标记接口(tagging interface)之一。或者称之为标记接口(marker interface)。接口的通常用途是确保一个类实现一个或一组特定的方法。标记接口不包含任何方法,他唯一的作用就是允许在类型查询中使用instanceof
即使clone的默认(浅拷贝)实现能够满足要求,还是需要实现Cloneable接口,将clone重新定义为public,在调用super.clone()。下面给出一个例子:
class Employee implements Cloneable
{
public Employee clone() throws CloneNotSupportedException
{
return (Employee) super.clone();
}
}
要建立深拷贝,(克隆对象中可变的实例域)
class Employee implements Cloneable
{
public Employee clone() throws CloneNotSupportedException
{
Employee cloned=(Employee) super.clone();
cloned.hireDay = (Date) hireDay.clone();
return cloned;
}
}
下列程序克隆了Employee类的一个实例,然后调用两个更改器方法。raiseSalary方法会改变salary域的值,而setHireDay方法改变hireDay域的状态,这两个更改器方法都不会影响原来的对象,因为clone建立了一个深拷贝。
package cc.openhome;
import java.util.Date;
import java.util.GregorianCalendar;
public class CloneTest {
public static void main(String[] args) {
try {
Employee original =new Employee("mama", 80000);
original.setHireDay(2018, 3, 19);
Employee copy=original.clone();
copy.raiseSalary(10);
copy.setHireDay(2008, 8, 8);
System.out.println("original="+original);
System.out.println("copy="+copy);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
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();
}
public Employee clone() throws CloneNotSupportedException
{
Employee cloned=(Employee) super.clone();
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();
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+"]";
}
}
original=Employee[name=mama,salary=80000.0,hireDay=Mon Mar 19 00:00:00 CST 2018]
copy=Employee[name=mama,salary=88000.0,hireDay=Fri Aug 08 00:00:00 CST 2008]
成功构建 (总时间: 0 秒)
run:
java 核心技术卷一笔记 6 .2.3 接口 lambda 表达式 内部类的更多相关文章
- Java核心技术卷一 · 笔记(2)
目录 1.多态.动态绑定 2.覆盖 3.阻止继承:final 类和方法 4.抽象类(abstract修饰) 5. 4 个访问修饰符: 6.toString() 7.对设计继承关系很有帮助的建议 8.接 ...
- java 核心技术卷一笔记 6 .2接口 lambda 表达式 内部类
6.2 接口实例 6.2.1 接口与回调 在java.swing包中有一个Timer类,可以使用它在到达给定的时间间隔时发出通告,假如程序中有一个时钟,就可以请求每秒钟获得一个通告,以便更新时钟的表盘 ...
- java 核心技术卷一笔记 6 .1接口 lambda 表达式 内部类
6.1 接口不是类,是对类的一组需求的描述,这些类需要遵守接口描述的统一格式进行定义.例如:Arrays类中sort方法(可以对对象数组进行排序)前提是对象所属的类必须实现了Comparable 接口 ...
- java 核心技术卷一笔记 6 .1.接口 lambda 表达式 内部类
6.1.2 接口不是类,不能实例化一个接口:但是可以声明接口的变量:Comparable x; 接口变量必须引用实现了接口的类对象:x = new Employee(); 检查一个对象是否属于某 ...
- java核心技术卷一笔记(1)
jdk是java开发工具包,里面包含了javac.jar.javadoc.java等工具,可以在bin目录中找到.有一个文件夹是jre,即jdk也包含了java运行环境.jre可单独安装,只是运行ja ...
- Java核心技术卷一 · 笔记(1)
目录 1.java的关键术语 2.==和equals 3.空串与 Null 串 4.构建字符串 5.封装 6.对象的三个主要特性 7.依赖(dependence).聚合(aggregation).继承 ...
- java核心技术卷一笔记(2)
---恢复内容开始--- 异常.断言 所有的异常都继承自Throwable类,异常包括已检查异常和未检查异常,应该抛出已检查异常,而未检查异常要么是不可控的(Error),要么是应该避免发生的(Run ...
- 【阅读笔记】Java核心技术卷一 #0
这是一篇备忘性质的读书笔记,仅记录个人觉得有用的知识点 本文作为一个目录索引,部分章节跳过 吐槽:此书中文翻译有不少地方不太通顺,这种情况我要把英文版对应的部分也读一遍才能明白(说实话,英文里的从句表 ...
- 对《Java核心技术卷一》读者的一些建议
<Java核心技术卷一>是唯一可以和<Java编程思想>媲美的一本 Java 入门书.单从技术的角度来看,前者更好一些.但上升到思想层面嘛,自然后者更好,两者的偏重点不同. 思 ...
随机推荐
- codevs-1204
1204 寻找子串位置 题目描述 Description 给出字符串a和字符串b,保证b是a的一个子串,请你输出b在a中第一次出现的位置. 输入描述 Input Description 仅一行包含两个 ...
- 菜鸟-@responsebody 理解-用法
@responsebody表示该方法的返回结果直接写入HTTP response body中一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@respo ...
- as3杂记
一.内存回收方式: 1.引用计数[没有互相引用] 2.标记清除[fp自己检测是否引用,没有引用的清除] 二.通信方式: 1.http:小型页游[charles抓包查看] 2.socket:大型页游[W ...
- 如何有效提升Unity Gear VR游戏性能
http://www.vr186.com/vr_news/vr_technical_area/1093.html 好的,所以你决定用 Unity 来做一个 VR 游戏,并选定了三星 Gear vr 为 ...
- 洛谷P3232 [HNOI2013]游走(高斯消元+期望)
传送门 所以说我讨厌数学……期望不会高斯消元也不会……好不容易抄好了高斯消元板子被精度卡成琪露诺了…… 首先,我们先算出走每一条边的期望次数,那么为了最小化期望,就让大的期望次数乘上小编号 边的期望次 ...
- 毕业N年后,请不要像我一样被档案烦死
目录 一. 提醒大学生:深刻重视档案,避免以后麻烦! 二.说说我因为档案造成的烦心事! 三.说说档案这档子事: 四.档案如此重要,为什么有些人却成了弃档族? 五.档案该怎么操作才能不当"弃档 ...
- Linux权限相关
权限分组 用户:文件所有者 用户组:多个用户的集合 其他:除了用户和用户组之外的任何用户 权限类别 r:表示读的权限 w:表示写的权限 x:表示执行的权限 s:表示setuid权限,允许用户以其拥有者 ...
- python+unittest 搭建简易的接口测试框架
主要介绍如何使用python+unittest快速搭建一个接口测试的框架 1.安装python unittest 2.新建一个python项目ApiTest 在setUp和setDown里设置一些需 ...
- day04 Calendar类
- jsp内置对象分析
1.html表单的提交方式比较: 1.1.get方式:将表单内容经过编码之后 ,通过URL发送, 使用get方式发送时有255个字符的限制. 1.2.post方式:将表单的内容通过http发送,pos ...