Java中5種創建對象的方法,你知道幾種?

作爲一個Java開發者,一種面向對象的語言,我們每天都創建很多對象。但後續我們開發中,採用了spring的依賴管理系統,我們就很少自己去創建對象了,全部交給容器去託管,那麼本篇文章回源塑本,講述一下java中能夠創建一個對象的5中方法。

本文最大的特色是,我不僅給出案例,還給出對應的字節碼解釋,從底層來解釋現象

1.使用new關鍵字

這是最常見也是最簡單的創建對象的方式了。通過這種方式,我們可以調用任意的構造函數(無參的和帶參數的)。

Employee emp1 = new Employee();

字節碼:

0: new           #19          // class com/fsx/demo/Employee
3: dup
4: invokespecial #21          // Method com/fsx/demo/Employee."":()V

2.使用Class類的newInstance方法

這個方法創建對象其實我們用得也比較多,but,這個newInstance方法調用無參的構造函數創建對象。所以類必須有public無參構造函數才行

Employee emp2 = (Employee) Class.forName("com.fsx.demo.mployee").newInstance();
或者
Employee emp2 = Employee.class.newInstance();

字節碼:

51: invokevirtual    #70    // Method java/lang/Class.newInstance:()Ljava/lang/Object;

3.使用Constructor類的newInstance方法

和Class類的newInstance方法很像。但是它可以調用任意構造函數創建對象,包括私有的。(所以即使你私有了構造函數,spring還是可以給你創建對象)

事實上Class的newInstance方法內部調用Constructor的newInstance方法。這也是衆多框架,如Spring、Hibernate、Struts等直接使用後者的原因

4.使用clone方法

無論何時我們調用一個對象的clone方法,jvm就會創建一個新的對象,將前面對象的內容全部拷貝進去。用clone方法創建對象並不會調用任何構造函數。
備註:要使用clone方法,我們需要先實現Cloneable接口並實現其定義的clone方法。

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

字節碼:

162: invokevirtual #87  // Method com/fsx/demo//Employee.clone ()Ljava/lang/Object;

5.使用反序列化

當我們序列化和反序列化一個對象,jvm會給我們創建一個單獨的對象。在反序列化時,jvm創建對象並不會調用任何構造函數。
備註:爲了反序列化一個對象,我們需要讓我們的類實現Serializable接口

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

字節碼:

261: invokevirtual  #118   // Method java/io/ObjectInputStream.readObject:()Ljava/lang/Object;

總結:

我們從上面的字節碼片段可以看到,除了第1個方法,其他4個方法全都轉變爲invokevirtual(創建對象的直接方法),第一個方法轉變爲兩個調用,new和invokespecial(構造函數調用)。

直接給出是否調用了構造函數的結論:

  1. 使用new關鍵字 } → 調用了構造函數
  2. 使用Class類的newInstance方法 } → 調用了構造函數
  3. 使用Constructor類的newInstance方法 } → 調用了構造函數
  4. 使用clone方法 } → 沒有調用構造函數
  5. 使用反序列化 } → 沒有調用構造函數

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章