zoukankan      html  css  js  c++  java
  • 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建立了一个深拷贝。

     1 package cc.openhome;
     2 import java.util.Date;
     3 import java.util.GregorianCalendar;
     4 public class CloneTest {
     5     public static void main(String[] args) {
     6         try {
     7             Employee original =new Employee("mama", 80000);
     8             original.setHireDay(2018, 3, 19);
     9             Employee copy=original.clone();
    10             copy.raiseSalary(10);
    11             copy.setHireDay(2008, 8, 8);
    12             System.out.println("original="+original);
    13             System.out.println("copy="+copy);
    14         } catch (CloneNotSupportedException e) {
    15             e.printStackTrace();
    16         }
    17     }
    18 }
    19 class Employee implements Cloneable
    20 {
    21     private String name;
    22     private double salary;
    23     private Date hireDay;
    24     public Employee(String name,double salary)
    25     {
    26         this.name=name;
    27         this.salary=salary;
    28         hireDay=new Date();
    29     }
    30     public Employee clone() throws CloneNotSupportedException
    31     {
    32         Employee cloned=(Employee) super.clone();
    33         cloned.hireDay = (Date) hireDay.clone();
    34         return  cloned;
    35     }
    36     public void setHireDay(int year,int month,int day)
    37     {
    38         Date newHireDay =new GregorianCalendar(year, month-1, day).getTime();
    39         hireDay.setTime(newHireDay.getTime());
    40     }
    41     public void raiseSalary(double byPercent)
    42     {
    43         double raise =salary*byPercent/100;
    44         salary+=raise;
    45     }
    46     public String toString()
    47     {
    48         return "Employee[name="+name+",salary="+salary+",hireDay="+hireDay+"]";
    49     }
    50 }
    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:
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/jinmoon/p/8599922.html
Copyright © 2011-2022 走看看