摘要:使用關鍵字這是最常見的創建對象的方法,并且也非常簡單。我們可以通過用以下方式創建對象或者使用構造函數類的方法與使用類的方法相似,類中有一個可以用來創建對象的函數方法。在反序列化中,虛擬機不會使用任何構造函數來創建對象。
作為Java開發者,我們每天都會創建大量的對象,但是,我們總是使用管理依賴系統(如Spring框架)來創建這些對象。其實還有其他方法可以創建對象,在接下來的文章中我會進行詳細介紹。
1.使用new關鍵字這是最常見的創建對象的方法,并且也非常簡單。通過使用這種方法我們可以調用任何我們需要調用的構造函數。
Employee emp1 = new Employee(); 0: new #19 // class org/programming/mitra/exercises/Employee 3: dup 4: invokespecial #21 // Method org/programming/mitra/exercises/Employee."":()V2.使用class類的newInstance方法
我們也可以使用class類的newInstance方法來創建對象。此newInstance方法調用無參構造函數以創建對象。
我們可以通過newInstance() 用以下方式創建對象:
Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance();
或者
Employee emp2 = Employee.class.newInstance(); 51: invokevirtual #70 // Method java/lang/Class.newInstance:()Ljava/lang/Object;3.使用構造函數類的 newInstance方法
與使用class類的newInstance方法相似,java.lang.reflect.Constructor類中有一個可以用來創建對象的newInstance()函數方法。通過使用這個newInstance方法我們也可以調用參數化構造函數和私有構造函數。
Constructorconstructor = Employee.class.getConstructor(); Employee emp3 = constructor.newInstance(); 111: invokevirtual #80 // Method java/lang/reflect/Constructor.newInstance:([Ljava/lang/Object;)Ljava/lang/Object;
這些 newInstance() 方法被認為是創建對象的反射手段。實際上,內部類的newInstance()方法使用構造函數類的 newInstance() 方法。這就是為什么后者是首選并且使用不同的框架如Spring, Hibernate, Struts等。
4.使用clone方法實際上無論何時我們調用clone方法,JAVA虛擬機都為我們創建了一個新的對象并且復制了之前對象的內容到這個新的對象中。使用 clone方法創建對象不會調用任何構造函數。
為了在對象中使用clone()方法,我們需要在其中實現可克隆類型并定義clone方法。
Employee emp4 = (Employee) emp3.clone(); 162: invokevirtual #87 // Method org/programming/mitra/exercises/Employee.clone ()Ljava/lang/Object;5.使用反序列化
無論何時我們對一個對象進行序列化和反序列化,JAVA虛擬機都會為我們創建一個多帶帶的對象。在反序列化中,JAVA虛擬機不會使用任何構造函數來創建對象。
對一個對象進行序列化需要我們在類中實現可序列化的接口。
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj")); Employee emp5 = (Employee) in.readObject(); 261: invokevirtual #118 // Method java/io/ObjectInputStream.readObject:()Ljava/lang/Object;
正如我們在以上的字節代碼片段中所看到的,除第一種被轉換為一個新的函數和一個 invokespecial 指令以外,其它4種方法都被調用并轉換為invokevirtual。
示例讓我們來看看準備創建對象的 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 { // By using new keyword Employee emp1 = new Employee(); emp1.setName("Naresh"); System.out.println(emp1 + ", hashcode : " + emp1.hashCode()); // By using Class class"s newInstance() method 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()); // By using Constructor class"s newInstance() method Constructorconstructor = Employee.class.getConstructor(); Employee emp3 = constructor.newInstance(); emp3.setName("Yogesh"); System.out.println(emp3 + ", hashcode : " + emp3.hashCode()); // By using clone() method Employee emp4 = (Employee) emp3.clone(); emp4.setName("Atul"); System.out.println(emp4 + ", hashcode : " + emp4.hashCode()); // By using Deserialization // 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
本文譯自:Dzone 譯者:慧都控件網-慧都小藝
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64968.html
摘要:這兩個操作符都是編譯器默認引入了類,最后都調用方法返回對象,臨時對象被回收,因此效率極為低下 Java String類筆記 聲明 文章均為本人技術筆記,轉載請注明出處https://segmentfault.com/u/yzwall String的不可變性 String的不可變性 // String declaration public final class String ...
摘要:構造函數模式定義構造函數模式是語言創建對象的通用方式。但兩種語言用構造函數創建對象的方式略有不同在中沒有類的概念,函數即為一等公民,因此,不必顯式聲明某個類,直接創建構造函數即可,類的方法和屬性在構造函數中或原型對象上處理。 工廠模式 定義:工廠模式非常直觀,將創建對象的過程抽象為一個函數,用函數封裝以特定接口創建對象的細節。通俗地講,工廠模式就是將創建對象的語句放在一個函數里,通...
摘要:一創建里流的四種方式第一種通過得方法串行流或者方法并行流創建。終止操作時一次性全部處理,稱為延遲加載篩選切片過濾中建操作。終止操作只有執行終止操作才會執行全部。即延遲加載結果中建操作。截斷流,使其元素不超過給定數量。返回流中最大值。 Stream api **Stream api 是java8 中提供的對集合處理的api , 對數據進行一系列的中間操作,元數據不會發生改變 ...
摘要:的三種常量池此外,有三種常量池,即字符串常量池又叫全局字符串池文件常量池運行時常量池。開始虛擬機把字符串常量池位置從永久代挪到堆,又徹底取消,把諸如之類的元數據都挪到堆之外管理。 前言 前陣子和朋友討論一個問題: 字符串常量歸常量池管理,那比如 String str = abc; abc這個對象是放在內存中的哪個位置,是字符串常量池中還是堆? 這句代碼的abc當然在常量池中,只有n...
摘要:代碼優化的最重要的作用應該是避免未知的錯誤。此舉能夠使性能平均提高。拋出異常首先要創建一個新的對象,接口的構造函數調用名為的本地同步方法,方法檢查堆棧,收集調用跟蹤信息。異常只能用于錯誤處理,不應該用來控制程序流程。 showImg(https://segmentfault.com/img/remote/1460000015379073); 代碼優化的最重要的作用應該是:避免未知的錯誤...
閱讀 1261·2021-09-02 13:36
閱讀 2714·2019-08-30 15:44
閱讀 2972·2019-08-29 15:04
閱讀 3193·2019-08-26 13:40
閱讀 3643·2019-08-26 13:37
閱讀 1172·2019-08-26 12:22
閱讀 1003·2019-08-26 11:36
閱讀 1214·2019-08-26 10:41