日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

CloneNotSupportedException的解決方案 + Object的clone方法分析

作者:Jothan Zhong 更新時(shí)間: 2024-01-10 編程語(yǔ)言

CloneNotSupportedException的解決方案

引入問(wèn)題:

在一次測(cè)試clone方法時(shí),D類(lèi)Override了Object類(lèi)的clone方法

public class D {

    private Integer A1;
    private Integer A2;

    public D() {
    }

    public D(Integer a1, Integer a2 {
        A1 = a1;
        A2 = a2;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
123456789101112131415161718

在測(cè)試類(lèi)中執(zhí)行clone方法報(bào)錯(cuò)了

public class Test5 {

    public static void main(String[] args) {

        D p  = new D();
        D p2 = null;
        try {
            p2 = (D)p.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        System.out.println(p == p2);

    }

}
12345678910111213141516

在這里插入圖片描述

拋出了 CloneNotSupportedException

尋找原因:

既然是重寫(xiě)自O(shè)bject的clone方法,那么去看看Object對(duì)該方法的定義:

protected native Object clone() throws CloneNotSupportedException;
1

其中對(duì)于異常拋出的描述如下:

Throws:
CloneNotSupportedException – if the object’s class does not support the Cloneable interface. Subclasses that override the clone method can also throw this exception to indicate that an instance cannot be cloned.

如果對(duì)象的class不實(shí)現(xiàn)Cloneable接口,子類(lèi)重寫(xiě)clone方法會(huì)同樣拋出異常表示實(shí)例不能被克隆;

哦?

那不意思就是說(shuō):你要不父類(lèi)實(shí)現(xiàn)Cloneable接口,要不就子類(lèi)實(shí)現(xiàn)Cloneable

兩個(gè)測(cè)試代碼:

測(cè)試1: 在父類(lèi)上實(shí)現(xiàn)Cloneable接口

public class TestClone {

    public static void main(String[] args) throws CloneNotSupportedException {
        Father father = new Father();
        Father fatherClone = (Father) father.clone();

        Son son = new Son();
        Son sonClone = (Son) son.clone();

        System.out.println(father==fatherClone);
        System.out.println(son==sonClone);

    }

}

class Father implements Cloneable{
    private Integer f1;
    private Integer f2;

    public Father() {
    }

    public Father(Integer f1, Integer f2) {
        this.f1 = f1;
        this.f2 = f2;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}


class Son extends Father{
    private Integer s1;
    private Integer s2;

    public Son() {
    }

    public Son(Integer s1, Integer s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

不出意外,沒(méi)有任何問(wèn)題

在這里插入圖片描述

測(cè)試2:在子類(lèi)上實(shí)現(xiàn)Cloneable接口

public class TestClone {

    public static void main(String[] args) throws CloneNotSupportedException {
//        Father father = new Father();
//        Father fatherClone = (Father) father.clone();

        Son son = new Son();
        Son sonClone = (Son) son.clone();

//        System.out.println(father==fatherClone);
        System.out.println(son==sonClone);

    }

}

class Father {
    private Integer f1;
    private Integer f2;

    public Father() {
    }

    public Father(Integer f1, Integer f2) {
        this.f1 = f1;
        this.f2 = f2;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}


class Son extends Father implements Cloneable{
    private Integer s1;
    private Integer s2;

    public Son() {
    }

    public Son(Integer s1, Integer s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

執(zhí)行父類(lèi)的clone報(bào)錯(cuò),但是執(zhí)行子類(lèi)的clone沒(méi)得問(wèn)題

在這里插入圖片描述

SO:

哪個(gè)類(lèi)的需要clone,就在那個(gè)類(lèi)在重寫(xiě)clone方法,并且在那個(gè)類(lèi)或者其父類(lèi)中實(shí)現(xiàn)Cloneable接口

詳細(xì)分析clone方法的實(shí)現(xiàn):

由于Object的clone方法是native修飾的,也就是虛擬機(jī)內(nèi)部實(shí)現(xiàn)的方法

根據(jù)Hotspot虛擬機(jī)定義,找到Object.c

在這里插入圖片描述

為什么要實(shí)現(xiàn)Cloneable接口?

在JVM_Clone方法中有這樣一段判斷:

在這里插入圖片描述

很明顯,虛擬機(jī)給你拋出的異常

為什么會(huì)出現(xiàn)地址不同的情況?

在這里插入圖片描述

很明顯,直接在堆內(nèi)存中執(zhí)行allocate方法開(kāi)辟新的對(duì)象空間

并返回一個(gè) oop 對(duì)象,也就是對(duì)象描述的指針(指向?qū)ο蟮氖椎刂罚?/p>

原文鏈接:https://blog.csdn.net/qq_43985303/article/details/135315353

  • 上一篇:沒(méi)有了
  • 下一篇:沒(méi)有了
欄目分類(lèi)
最近更新