五種方法建立java物件,你知道幾種呢?

Java正道的光發表於2020-11-14

五種方法建立java物件

作為Java開發人員,我們通常每天都會建立許多物件,但是我們總是使用新的或依賴管理系統(例如Spring)來建立這些物件。但是,有更多方法可以建立本文中將要研究的物件。

用Java建立物件的共有5種核心方式,下面將以其示例加以說明,然後介紹建立物件的行的位元組碼。但是,有很多API可以為我們建立物件,但是這些API還將間接使用這5種核心方式之一,例如Spring BeanFactory

 

 

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

 

1.使用新關鍵字

這是建立物件的最常見和常規的方法,也是一種非常簡單的方法。通過使用此方法,我們可以呼叫要呼叫的任何建構函式(無引數的建構函式和引數化的)。

1

Employee emp1 = new Employee();

  

 

 

2.使用Class類的newInstance()方法

我們還可以使用Class類的newInstance()方法建立一個物件。此newInstance()方法呼叫no-arg建構函式來建立物件。

我們可以通過newInstance()通過以下方式建立物件:

1

2

3

4

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

Or

 

Employee emp2 = Employee.class.newInstance();

  

 

3.使用構造方法類的newInstance()方法

Class類的newInstance()方法類似,java.lang.reflect.Constructor類中有一個newInstance()方法可用於建立物件。我們還可以使用此newInstance()方法來呼叫引數化建構函式和私有建構函式。

1

2

3

Constructor<Employee> constructor = Employee.class.getConstructor();

 

Employee emp3 = constructor.newInstance();

  

 

這兩種newInstance()方法都被稱為建立物件的反射方式。實際上,Class類的newInstance()方法在內部使用了Constructor類的newInstance()方法。這就是為什麼最好使用後一種方法,並且也將其用於諸如Spring,Hibernate,Struts等不同框架的原因。要了解這兩種newInstance()方法之間的區別,請閱讀使用Example在Java中通過Reflection建立物件。

 

4.使用clone()方法:

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

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

1

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

  

 

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

 

5.使用反序列化

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

1

2

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

Employee emp5 = (Employee) in.readObject();

  

 

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

例:
讓我們考慮一個我們要為其建立物件的Employee類:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

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 boolean equals(Object o) {

        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        Employee employee = (Employee) o;

        return Objects.equals(name, employee.name);

    }

 

    @Override

    public int hashCode() { return Objects.hash(name); }

 

    @Override

    public String toString() { return String.format("Employee{name='%s'}", name); }

 

    @Override

    public Object clone() {

        Object obj = null;

        try {

            obj = super.clone();

        catch (CloneNotSupportedException e) {

            e.printStackTrace();

        }

        return obj;

    }

}

  

 

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

public class ObjectCreation {

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

 

        // 1. Using new keyword

        Employee emp1 = new Employee();

        emp1.setName("emp1");

 

 

        // 2. Using Class class's newInstance() method

        Employee emp2 = Employee.class.newInstance();

        emp2.setName("emp2");

 

 

        // 3. Using Constructor class's newInstance() method

        Constructor<Employee> constructor = Employee.class.getConstructor();

        Employee emp3 = constructor.newInstance();

        emp3.setName("emp3");

 

        // 4. Using clone() method

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

        emp4.setName("emp4");

 

 

        // Serialization

        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"))) {

            out.writeObject(emp4);

        }

 

        // 5. Using Deserialization

        Employee emp5;

        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"))) {

            emp5 = (Employee) in.readObject();

            emp5.setName("emp5");

        }

 

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

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

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

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

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

    }

}

  

該程式將給出以下輸出:

1

2

3

4

5

6

7

8

Employee Constructor Called...

Employee Constructor Called...

Employee Constructor Called...

Employee{name='emp1'}, hashcode : 3117192

Employee{name='emp2'}, hashcode : 3117193

Employee{name='emp3'}, hashcode : 3117194

Employee{name='emp4'}, hashcode : 3117195

Employee{name='emp5'}, hashcode : 3117196

  

完整的Java初級,高階對應的學習路線和資料!專注於java開發。分享java基礎、原理性知識、JavaWeb實戰、spring全家桶、設計模式、分散式及面試資料、開源專案,助力開發者成長!

相關文章