1. 程式人生 > 其它 >Java中5種建立物件的方式小筆記

Java中5種建立物件的方式小筆記

方式是否呼叫了建構函式
使用new關鍵字
使用Class類的newInstance方法
使用Constructor類的newInstance方法
使用clone方法
使用反序列化

建立一個Cat類來說明,該類實現了Cloneable和Serializable介面。

package com.joshua317;

import java.io.Serializable;

public class Cat implements Cloneable, Serializable {
    private String name;
    private int age;

    public Cat() {
        System.out.println("呼叫無參建構函式");
    }

    public Cat(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 Cat clone() {
        Cat cat = null;
        try {
            cat = (Cat)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return cat;
    }

    @Override
    public String toString() {
        return "Cat [name=" + name + ", age=" + age +  "]";
    }
}

注意:

1.java.lang.CloneNotSupportedException 原因是沒有 implements Cloneable。

2.java.io.NotSerializableException 原因是沒有 implements Serializable。

接下來我們程式設計來說明:

package com.joshua317;


import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Main {

    public static void main(String[] args) {

        Cat cat1 = null, cat2 = null,cat3 = null ,cat4 = null ,cat5 = null;
        /**
         * 1.使用new關鍵字;
         * 通過使用這種方法我們可以呼叫任何我們需要呼叫的建構函式。
         */
        cat1 = new Cat();
        cat1.setName("小貓1");
        cat1.setAge(1);
        System.out.println("cat1:" + cat1);
        System.out.println();

        /**
         * 2.使用class類的newInstance方法
         * 此newInstance()方法呼叫無參建構函式以建立物件。
         */
        try {
            cat2 = (Cat) Class.forName("com.joshua317.Cat").newInstance();
            cat2.setName("小貓2");
            cat2.setAge(2);

            System.out.println("cat2:" + cat2);
            System.out.println();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        /**
         * 3.使用建構函式類的newInstance方法;
         * 與使用class類的newInstance()方法相似
         * java.lang.reflect.Constructor類中有一個可以用來建立物件的newInstance()函式方法。
         * 通過使用這個newInstance()方法我們也可以呼叫引數化建構函式和私有建構函式。
         */
        Constructor  constructor = null;
        try {
            constructor = Cat.class.getConstructor();
            try {
                cat3 = (Cat)constructor.newInstance();
                cat3.setName("小貓3");
                cat3.setAge(3);

                System.out.println("cat3:" + cat3);
                System.out.println();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        /**
         * 4.使用clone方法
         *
         * 在程式開發中,有時可能好會遇到下列情況:
         * 已經存在一個物件A,現在需要一個與物件A完全相同的B物件,並對B物件的值進行修改,但是A物件的原有的屬性值不能改變。
         * 這時,如果使用java提供的物件賦值語句,當修改B物件值後,A物件的值也會被修改。
         * 那麼應該如何實現建立一個和物件A完全相同的物件B,而且修改物件B時,物件A的屬性值不被改變呢?
         *
         * clone方法可以完成物件的淺克隆。
         * 所謂淺克隆就是說被克隆的物件的各個屬性都是基本型別,而不是引用型別(介面、類、陣列),
         * 如果存在引用型別的屬性,則需要進行深克隆。
         *
         * 實際上無論何時我們呼叫clone() 方法,JAVA虛擬機器都為我們建立了一個新的物件並且複製了之前物件的內容到這個新的物件中。
         * 使用 clone()方法建立物件不會呼叫任何建構函式。
         * 為了在物件中使用clone()方法,我們需要在其中實現可克隆型別並定義clone()方法。
         */
        cat4 = (Cat) cat1.clone();
        cat4.setName("小貓4");
        cat4.setAge(4);

        System.out.println("cat4:" + cat4);
        System.out.println();
        /**
         * 5.使用反序列化
         * 無論何時我們對一個物件進行序列化和反序列化,JAVA虛擬機器都會為我們建立一個單獨的物件。
         * 在反序列化中,JAVA虛擬機器不會使用任何建構函式來建立物件。
         * 對一個物件進行序列化需要我們在類中實現可序列化的介面。
         */


        //序列化
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream("./cat.ser");
            try {
                ObjectOutputStream out = new ObjectOutputStream(fileOut);
                out.writeObject(cat1);
                out.close();
                fileOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


        //反序列化
        ObjectInputStream in = null;
        try {
            FileInputStream fileIn = new FileInputStream("./cat.ser");
            in = new ObjectInputStream(fileIn);
            try {
                cat5 = (Cat) in.readObject();
                in.close();
                fileIn.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("cat5:" +cat5);
        System.out.println();
    }
}