最全--Java中建立物件的5種方法

DevHappy發表於2020-10-09

將會列舉5種方法去建立 Java 物件,以及他們如何與建構函式互動,並且會有介紹如何去使用這些方法的示例。

作為一個 Java 開發人員,我們每天都會建立大量的 Java 物件,但是我們通常會使用依賴管理系統去建立這些物件,例如 Spring 。然而,我們可以有更多的方式去建立物件,讓我們一起在文章中去學習這些方法吧。

這裡列舉在 Java 中建立物件的五種方式,下面將介紹它們的示例,以及建立物件的行的位元組碼。

  
1.使用 new 關鍵字建構函式會被呼叫
2.使用 Class 類的 newInstance()建構函式會被呼叫
3.使用 Constructor 類的 newInstance()建構函式會被呼叫
4.使用 clone() 方法無建構函式呼叫
5.使用 序列化無建構函式呼叫

如果您將執行最後給出的程式,您將看到方法1、2、3使用建構函式建立物件,而4、5沒有呼叫建構函式建立物件。

1.使用 new 關鍵字

這是建立一個物件最通用、常規的方法,同時也是最簡單的方式。通過使用此方法,我們可以呼叫任何要呼叫的建構函式(預設使用無參建構函式)。

Employee emp1 = new Employee();

2.使用 Class 類的 newInstance()
我們能夠使用 Class 類的 newInstance() 方法建立物件。這個 newInstance() 方法將呼叫無參構造方法去建立一個物件。

在下述程式碼中,我們通過呼叫 newInstance() 去建立一個物件:

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance();

或者:

Employee emp2 = Employee.class.newInstance();

3.使用 Constructor 類的 newInstance()
與 Class 類中的 newInstance() 方法相似,在此我們將使用 java.lang.reflect.Constructor 類中的 newInstance() 方法建立物件。通過使用這個 newInstance() 方法我們能夠呼叫有參建構函式和私有建構函式。

 

Constructor constructor = Employee.class.getConstructor(); 
Employee emp3 = constructor.newInstance();

這兩個 newInstance() 方法都被稱為建立物件的反射方法。實際上, Class 類的 newInstance() 方法內部使用 Constructor 類的 newInstance() 方法。這就是為什麼後者更受歡迎,並且也被 Spring、Hibernate、Structs 等不同的框架所使用的原因。

 

4.使用 Clone() 方法

每當我們對任何物件呼叫 clone() 時,jvm 都會為我們建立一個新物件,並將前一個物件的所有內容複製到其中。使用 clone 方法建立物件不會呼叫任何建構函式。

要在物件上使用 clone() 方法,我們需要實現 Cloneable 並在其中定義 clone() 方法。

Employee emp4 = (Employee) emp3.clone();

Java克隆是Java社群中最有爭議的話題,它的確有其缺點,但是在物件完全滿足Java克隆的強制條件之前,它仍然是建立任何物件的副本的最流行和最簡單的方法。

5.使用反序列化

每當我們序列化和反序列化物件時,JVM就會為我們建立一個單獨的物件。在反序列化中,JVM不使用任何建構函式來建立物件。要反序列化物件,我們需要在類中實現Serializable介面。

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
 Employee emp5 = (Employee) in.readObject();

正如我們在上面的位元組碼中可以看到的那樣,所有四個方法呼叫都轉換為invokevirtual(這些方法直接處理物件的建立),但第一個方法轉換為兩個呼叫,一個是new,另一個是invokespecial(對建構函式的呼叫)。

示例

建立物件的 Employee 類:

class Employee implements Cloneable, Serializable 

    private static final long serialVersionUID = 1L;

    private String name    

    public Employee() {
        System.out.println("Employee Constructor Called...");
    }   

    public String getName() {
        return name;
    }

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

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }    

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

    @Override
    public Object clone() {
        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

在下面的 Java 程式中,我們將以5種方式建立 Employee 物件。

public class ObjectCreation {
    public static void main(String... args) throws Exception {

       // 1.使用 new 關鍵字
        Employee emp1 = new Employee();
        emp1.setName("Naresh");

        System.out.println(emp1 + ", hashcode : " + emp1.hashCode());

        // 2.使用 Class 類的 newInstance()
        Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
                               .newInstance();

        // Or we can simply do this
        // Employee emp2 = Employee.class.newInstance();
        emp2.setName("Rishi");
        System.out.println(emp2 + ", hashcode : " + emp2.hashCode());

        //3.使用 Constructor 類的 newInstance()
        Constructor<Employee> constructor = Employee.class.getConstructor();
        Employee emp3 = constructor.newInstance();
        emp3.setName("Yogesh");
        System.out.println(emp3 + ", hashcode : " + emp3.hashCode());

        // 4.使用 Clone() 方法
        Employee emp4 = (Employee) emp3.clone();
        emp4.setName("Atul");
        System.out.println(emp4 + ", hashcode : " + emp4.hashCode());

        // 使用序列化
        // Serialization
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));
        out.writeObject(emp4);
        out.close();

        //Deserialization
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
        Employee emp5 = (Employee) in.readObject();
        in.close();
        emp5.setName("Akash");
        System.out.println(emp5 + ", hashcode : " + emp5.hashCode());
    }
}

此程式執行將有以下輸出:

Employee Constructor Called...
Employee [name=Naresh], hashcode : -1968815046
Employee Constructor Called...
Employee [name=Rishi], hashcode : 78970652
Employee Constructor Called...
Employee [name=Yogesh], hashcode : -1641292792
Employee [name=Atul], hashcode : 2051657
Employee [name=Akash], hashcode : 63313419

原文:https://dzone.com/articles/5-different-ways-to-create-objects-in-java-with-ex

相關文章