zoukankan      html  css  js  c++  java
  • JAVA如何实现深拷贝

    转载请注明出处,谢谢!

    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 ,当然equals方法是如此重写过的

    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:
    true
    false
    true
    

    // 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

  • 相关阅读:
    Bootstrap里的文件分别代表什么意思及其引用方法
    selenium alert JS弹窗问题处理
    Selenium爬取元素定位
    mysql 启动提示:错误2系统找不到指定文件
    团体程序设计天梯赛-练习集(一)(string.find()、string.erase()、string.insert()、map容器、L1-002 (*)、L1-005、L1-063、L1-058、L1-054 (*)、L1-003 )
    PTA基础编程题目集(四)(直接插入排序、希尔排序、大数阶乘、6-10 阶乘计算升级版、6-11 求自定类型元素序列的中位数)
    PTA基础编程题目集(三)(7-29 删除字符串中的子串 、7-26 单词长度、6-7 统计某类完全平方数)
    PTA基础编程题目集(二)(输入带空格字符串,字符数组、7-28 猴子选大王(*)、7-30 字符串的冒泡排序、7-31 字符串循环左移 、7-1 厘米换算英尺英寸、7-35 有理数均值(*))
    PTA基础编程题目集(一)(pow函数用法,7-13 日K蜡烛图、7-18 二分法求多项式单根(*))
    水题
  • 原文地址:https://www.cnblogs.com/LittleTreasureBox/p/8848714.html
Copyright © 2011-2022 走看看