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(建構函式呼叫)。
直接給出是否呼叫了建構函式的結論:
- 使用new關鍵字 } → 呼叫了建構函式
- 使用Class類的newInstance方法 } → 呼叫了建構函式
- 使用Constructor類的newInstance方法 } → 呼叫了建構函式
- 使用clone方法 } → 沒有呼叫建構函式
- 使用反序列化 } → 沒有呼叫建構函式