Java中創(chuàng)建對(duì)象的方式

一:Java中創(chuàng)建對(duì)象的方式

1:使用new操作符創(chuàng)建對(duì)象。 
2:使用clone()復(fù)制對(duì)象。 
3:使用反序列化來(lái)創(chuàng)建對(duì)象。
4:反射機(jī)制創(chuàng)建對(duì)象。
5:Unsafe.allocateInstance()創(chuàng)建對(duì)象。

示例

/**
 * <p>
 *  Java中創(chuàng)建對(duì)象的方式
 * </p>
 * @author: zhu.chen
 * @date: 2020/7/27
 * @version: v1.0.0
 */
public class CreateObjectTest {

    public static void main(String[] args) throws CloneNotSupportedException, IllegalAccessException, InstantiationException, IOException, ClassNotFoundException {
        // 1:通過(guò)new創(chuàng)建對(duì)象
        Person newPerson = new Person("zhangsan", 1);
        System.out.println(newPerson);
        // 2:通過(guò)clone():屬性需要實(shí)現(xiàn)Cloneable接口,并重寫(xiě)Object類的clone()。
        Person clonePerson = (Person) newPerson.clone();
        System.out.println(clonePerson);
        // 3:通過(guò)序列化和反序列化:需要實(shí)現(xiàn)序列化接口Serializable
        Person serializablePerson = serializablePerson();
        System.out.println(serializablePerson);
        // 4:通過(guò)反射創(chuàng)建對(duì)象:通過(guò)newInstance()來(lái)創(chuàng)建時(shí),必須有無(wú)參構(gòu)造函數(shù)。
        Class clazz = Person.class;
        Person reflectionPerson = (Person) clazz.newInstance();
        reflectionPerson.setAge(2);
        reflectionPerson.setName("xiaoming");
        System.out.println(reflectionPerson);
        // 5:Unsafe.allocateInstance
        Person unsafePerson = (Person) unsafe.allocateInstance(Person.class);
        unsafePerson.setName("xiaobai");
        unsafePerson.setAge(5);
        System.out.println(unsafePerson);
        // 6:BeanUtils的拷貝
        Person beanPerson = new Person();
        BeanUtils.copyProperties(newPerson, beanPerson);
        System.out.println(beanPerson);
    }

    /**
     * 獲取unsafe類
     */

    static Unsafe unsafe;

    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 序列化對(duì)象
     *
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private static Person serializablePerson() throws IOException, ClassNotFoundException {
        /**
         * 網(wǎng)絡(luò)傳輸和磁盤(pán)IO會(huì)存在序列化對(duì)象來(lái)進(jìn)行傳輸和存儲(chǔ)。
         * 適用場(chǎng)景:IO(網(wǎng)絡(luò)IO、磁盤(pán)IO)
         */
        // 序列化
        Person person = new Person("xiaohong", 4);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
        oos.writeObject(person);
        // 反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"));
        return (Person) ois.readObject();
    }

    private static class Person implements Cloneable, Serializable {

        private static final long serialVersionUID = -5463972443328267182L;

        private String name;

        private int age;

        public Person() {
        }

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

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

}

注:同步更新于CreateObjectTest

二:Java的深淺拷貝

淺拷貝:如果屬性是基本類型,拷貝的就是基本類型的值;如果屬性是內(nèi)存地址(引用類型),拷貝的就是內(nèi)存地址。
深拷貝:深拷貝會(huì)拷貝所有的屬性,并拷貝屬性指向的動(dòng)態(tài)分配的內(nèi)存。
深淺拷貝.png
1:使用new操作符創(chuàng)建對(duì)象:深拷貝
2:使用clone()復(fù)制對(duì)象:深拷貝、淺拷貝(具體看寫(xiě)法)
3:使用反序列化來(lái)創(chuàng)建對(duì)象:深拷貝
4:反射機(jī)制創(chuàng)建對(duì)象:深拷貝
5:Unsafe.allocateInstance()創(chuàng)建對(duì)象:深拷貝

三:如何選擇拷貝方式
對(duì)象的拷貝一般都是用第三方工具類實(shí)現(xiàn),比如spring-beans中的BeanUtils#copyProperties。

1:如果對(duì)象的屬性全是基本類型的,那么可以使用淺拷貝。
2:如果對(duì)象有引用屬性,那就要基于具體的需求來(lái)選擇淺拷貝還是深拷貝。如果對(duì)象引用任何時(shí)候都不會(huì)被改變,那么沒(méi)必要使用深拷貝,只需要使用淺拷貝就行了。如果對(duì)象引用經(jīng)常改變,那么就要使用深拷貝。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容