溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java設(shè)計模式中的原型模式怎么實(shí)現(xiàn)

發(fā)布時間:2023-04-27 09:41:49 來源:億速云 閱讀:95 作者:zzz 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Java設(shè)計模式中的原型模式怎么實(shí)現(xiàn)”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    原型模式

    在Java中,原型模式是一種創(chuàng)建型設(shè)計模式,它允許通過復(fù)制一個現(xiàn)有對象來創(chuàng)建一個新對象,而不是通過創(chuàng)建新的對象來初始化一個對象,原型模式是一種基于克隆的設(shè)計模式,通過復(fù)制現(xiàn)有對象的數(shù)據(jù)來創(chuàng)建新的對象.

    原型模式需要實(shí)現(xiàn)Cloneable接口并重寫Object類中的clone()方法,在重謝clone()方法時,需要調(diào)用super.clone()方法來創(chuàng)建一個新的對象,并復(fù)制原始對象中的所有屬性.默認(rèn)情況下,Java中的Object類提供的clone()方法會執(zhí)行淺拷貝,如果原始對象中包含引用類型的成員變量,則需要進(jìn)行深拷貝操作,以確保新對象中所有成員變量都是獨(dú)立的.

    深拷貝與淺拷貝

    淺拷貝(Shallow Copy)會創(chuàng)建一個新的對象,該對象具有與原始對象相同的屬性值.但是,如果原始對象包含對其他對象的引用,則新對象也將包含對相同對象的引用.換句話說,新對象僅僅是原始對象的一個副本,而不是獨(dú)立的對象.

    深拷貝(Deep Copy)則是創(chuàng)建一個新的對象,該對象具有與原始對象相同的屬性值,但是它會遞歸的復(fù)制對象圖中所有的對象,而不是只復(fù)制引用.換句話說,深拷貝會創(chuàng)建一個完全獨(dú)立的新對象,該對象與原始對象沒有任何關(guān)聯(lián).

    區(qū)別:

    • 對于基本數(shù)據(jù)類型,淺拷貝和深拷貝沒有區(qū)別,因?yàn)榛緮?shù)據(jù)類型在內(nèi)存中儲存為值.但是對于引用類型,淺拷貝和深拷貝會有不同的行為.淺拷貝只復(fù)制對象本身以及其中的基本數(shù)據(jù)類型成員,而不會復(fù)制引用類型成員.因此,如果原始對象中包含引用類型成員,淺拷貝得到的對象中的引用類型成員與原始對象中的相同,即兩者指向同一塊內(nèi)存地址.而深拷貝則會遞歸的復(fù)制所有的引用類型成員,因此得到的對象中的引用類型成員與原始對象中的不同,即兩者指向不同的內(nèi)存地址.

    • 淺拷貝速度相對較快,因?yàn)樗粡?fù)制了對象本身以及其中的基本數(shù)據(jù)類型成員.而深拷貝速度相對較慢,因?yàn)樗枰f歸的復(fù)制所有引用類型成員.

    應(yīng)用場景:

    • 淺拷貝通常用于快速創(chuàng)建對象副本,且原始對象中不包含引用類型成員的情況下,可以使用淺拷貝.比如,當(dāng)需要多個對象共享某些狀態(tài)時,可以使用淺拷貝來快速創(chuàng)建副本

    • 深拷貝通常用于創(chuàng)建完全獨(dú)立的對象,且原始對象中包含引用類型成員的情況下,可以使用深拷貝

    淺拷貝示例代碼

    @Data
    public class Person implements Cloneable{
        private String name;
        private int age;
        private Address address;
        public Person(String name, int age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    @Data
    public class Address {
        private String city;
        private String street;
        public Address(String city, String street) {
            this.city = city;
            this.street = street;
        }
    }

    測試淺拷貝

    package com.fanqiechaodan.prototype.copy.shollow;
    import com.alibaba.fastjson.JSON;
    /**
     * @Classname Demo
     * @Description 淺拷貝
     */
    public class Demo {
        public static void main(String[] args) throws CloneNotSupportedException {
            Person person1 = new Person("張三", 18, new Address("上海", "南京路"));
            Person person2 = (Person) person1.clone();
            System.out.println(JSON.toJSONString(person1));
            System.out.println(JSON.toJSONString(person2));
            System.out.println("淺拷貝后:");
            person1.getAddress().setCity("南京");
            System.out.println(JSON.toJSONString(person1));
            System.out.println(JSON.toJSONString(person2));
        }
    }

    Java設(shè)計模式中的原型模式怎么實(shí)現(xiàn)

    深拷貝示例代碼

    @Data
    public class Person implements Serializable {
        private String name;
        private int age;
        private Address address;
        public Person(String name, int age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
        @Override
        protected Object clone() {
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(this);
                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bis);
                return ois.readObject();
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    @Data
    public class Address implements Serializable {
        private String city;
        private String street;
        public Address(String city, String street) {
            this.city = city;
            this.street = street;
        }
    }

    測試深拷貝

    package com.fanqiechaodan.prototype.copy.deep;
    import com.alibaba.fastjson.JSON;
    import org.springframework.util.SerializationUtils;
    import java.io.IOException;
    /**
     * @Classname Demo
     * @Description 深拷貝
     */
    public class Demo {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            Person person1 = new Person("張三", 18, new Address("上海", "南京路"));
            // 重寫clone完成深拷貝
            Person person2 = (Person) person1.clone();
            // 使用工具類完成深拷貝
            Person person3 = (Person) SerializationUtils.deserialize(SerializationUtils.serialize(person1));
            System.out.println(JSON.toJSONString(person1));
            System.out.println(JSON.toJSONString(person2));
            System.out.println(JSON.toJSONString(person3));
            System.out.println("深拷貝后:");
            person1.getAddress().setCity("南京");
            System.out.println(JSON.toJSONString(person1));
            System.out.println(JSON.toJSONString(person2));
            System.out.println(JSON.toJSONString(person3));
        }
    }

    Java設(shè)計模式中的原型模式怎么實(shí)現(xiàn)

    原型模式代碼

    原型類代碼

    @Data
    public class Person implements Cloneable{
        private String name;
        private int age;
        private Address address;
        public Person(String name, int age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    @Data
    public class Address {
        private String city;
        private String street;
        public Address(String city, String street) {
            this.city = city;
            this.street = street;
        }
    }

    測試

    package com.fanqiechaodan.prototype;
    import com.alibaba.fastjson.JSON;
    /**
     * @Classname Demo
     * @Description
     */
    public class Demo {
        public static void main(String[] args) throws CloneNotSupportedException {
            Person person1 = new Person("張三", 18, new Address("北京", "青年路"));
            Person person2 = (Person) person1.clone();
            System.out.println(JSON.toJSONString(person1));
            System.out.println(JSON.toJSONString(person2));
        }
    }

    Java設(shè)計模式中的原型模式怎么實(shí)現(xiàn)

    需要注意的是,在使用Cloneable接口實(shí)現(xiàn)原型模式時,需要注意以下幾點(diǎn):

    • 要使用克隆方法,必須確保該對象實(shí)現(xiàn)了Cloneable接口.否則,在調(diào)用clone方法時會拋出CloneNotSupportedException異常

    • 調(diào)用clone方法返回的是一個淺拷貝對象,如果對象包含了引用類型的成員變量,那么這些成員變量依然會被多個對象共享.

    • 在實(shí)現(xiàn)clone方法時,需要注意對成員變量的處理,特別是對引用類型的成員變量的處理.如果需要實(shí)現(xiàn)深拷貝,可以通過重寫clone方法來實(shí)現(xiàn).

    “Java設(shè)計模式中的原型模式怎么實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI