博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA如何实现深拷贝
阅读量:6717 次
发布时间:2019-06-25

本文共 3824 字,大约阅读时间需要 12 分钟。

protected 域(或方法)微妙的规则

protected 域(或方法)对本包内的所有类可见(当然包括子类),那么,子类可以获得访超类受保护域(或方法)的权利,但是,若子类和超类不在同一个包下,就不能访问超类对象的这个受保护域(或方法)。也就是说,不在一个包下,子类中不能通过一个父类对象的引用来获得父类受保护的域(或方法),测试如下。

package protect2;public class P{    protected int a;    public P(){}    public P(int a){        this.a = a;    }    protected void fun(){        System.out.println("父类protected方法");    }}
package protect2;public class ProtectedTest {    public String s;    public ProtectedTest(String s) {        this.s = s;    }    P ap = new P(10);    void foo() {        ap.fun();        System.out.println("ap.a " + ap.a);    }    public static void main(String[] args) {        ProtectedTest test = new ProtectedTest("abcdef");        test.foo();        System.out.println(test.s);    }}
package protect;import protect2.P;class C extends P{    public int b;    public C(int a,int b){        super(a);        this.b = b;    }    public void afun(){        P pp = new P(10);        System.out.println("C.a= " + a);        System.out.println("P.a= " + pp.a);//ERROR:The field P.a is not visible        pp.fun(); //ERROR:The method fun() from the type P is not visible    }

浅拷贝与深拷贝

Object类对自己的具体子类的域一无所知,Object类的clone方法只是将各个域进行拷贝。数值或基本类型不会出现问题,但是,如果在对象中包含了引用对象,这些对象的内容没有被自我复制,拷贝的结果也即是原始对象和拷贝对象引用着同一个引用对象(一般地,动词“引用”可理解为“管理”,就是指向同一内存)。

浅拷贝满足:

  1. x.clone() != xtrue
  2. x.clone().getClass() == x.getClass()true
  3. ((x.clone().field1 ) == (x. field1))&& … &&((x.clone().fieldN )==(x. fieldN))也为 true

如果原始对象与浅拷贝对象共同引用(管理、指向)的引用对象是不可变的,将不会产生任何问题,如,引用对象是String类对象;或引用对象在其生命周期不会发生变化,具体来说,管理它的类中没有更改它的方法,也没有返回对它引用的方法(分享其管理权的方法)。

如果原始对象管理的引用对象是可变的,就必须需重新定义clone方法,来实现深层次的拷贝。要对涉及的每一个类,判断以下两点:

  • 默认的clone方法是否满足需求。
  • 默认的clone方法是否能通过调用可变引用对象的clone方法得到解决。

对涉及的每一个类,深拷贝要满足:

  1. x.clone() != xtrue
  2. x.clone().getClass() == x.getClass()true
  3. x.clone().equals(x)也为 true ,当然。

Object类中的clone方法被声明为protected,防止出现文章开头所提到的,子类和超类不在同一个包下的情况,要声明clonepublic,来实现深拷贝:

import java.util.Date;public class EqualsT {    public static void main(String[] args) throws CloneNotSupportedException {        Date hireDay = new Date();        Employee e1 = new Employee("Tommy", 10, "9998", hireDay);        Employee e2 = new Employee("Tommy", 10, "9998", hireDay);        System.out.println(e1.equals(e2));        System.out.println(e1 == e2);        Employee e3 = (Employee) e1.clone();        System.out.println(e1.equals(e3));    }}//Cloneable为标记接口,接口内没有方法。class Employee implements Cloneable {    String name;    int age;    String salary;    Date hireDay;    public Employee(String name, int age, String salary, Date hireDay) {        super();        this.name = name;        this.age = age;        this.salary = salary;        this.hireDay = hireDay;    }    @Override    public boolean equals(Object otherObject) {        if (this == otherObject)            return true;        if (otherObject == null)            return false;        if (!(otherObject instanceof Employee))            return false;        Employee other = (Employee) otherObject;        return name.equals(other.name) && age == other.age && salary.equals(other.salary)                && hireDay.equals(other.hireDay);    }    @Override    protected Object clone() throws CloneNotSupportedException {        // call Object.clone()        Employee cloned = (Employee) super.clone();        // call mutable fields        cloned.hireDay = (Date) hireDay.clone();        return cloned;    }}Output:truefalsetrue

// JDK中Date类的克隆方法public Object clone() {        Date d = null;        try {            d = (Date)super.clone();            if (cdate != null) {                d.cdate = (BaseCalendar.Date) cdate.clone();            }        } catch (CloneNotSupportedException e) {} // Won't happen        return d;    }


——@guoyangde http://www.cnblogs.com/LittleTreasureBox/p/8904016.html

转载于:https://www.cnblogs.com/LittleTreasureBox/p/8848714.html

你可能感兴趣的文章
jvisualvm 工具使用
查看>>
《精通Python设计模式》学习行为型之责任链模式
查看>>
How to Limit NodeRunner.exe High Memory, CPU Usage
查看>>
solr7.1.0学习笔记(10)---Solr发布到Tomcat
查看>>
洛谷P1435 回文字串(dp)
查看>>
php 会话控制(关于session的维护与生命周期)
查看>>
tomcat PermGen space
查看>>
高阶函数:声明、实现(定义)与调用
查看>>
splash 安装
查看>>
mysql数据库优化课程---15、mysql优化步骤
查看>>
数据库路由中间件MyCat - 使用篇(4)
查看>>
Java程序开发中的简单内存分析
查看>>
Java中的Future相关
查看>>
CGAL Catmull-Clark Subdivide Surface
查看>>
赛车入门 -- 专有技术名词
查看>>
接收IWebBrowser2的自动化事件
查看>>
需求入门: 需求工程=需求开发+需求管理
查看>>
androidmanifest.xml权限中文说明
查看>>
matlab练习程序(感知哈希对比图片)
查看>>
多媒体指令(图像灰度化)
查看>>