Java 是面向對象的語言,不可避免的,「對象」這個概念是 Java 語言的核心部分,這裏來簡單討論一下在 Java 中建立通常對象的方法。數組
總結下來有如下4種建立對象的方法:ide
最多見的 Java 對象的構造方法,經過調用類提供的構造器建立對象。spa
Java 反射中有一個 newInstance() 方法,能夠建立對象,步驟以下:3d
示例代碼:code
1 public class MethodNewInstance { 2 3 public static void main(String[] args) throws Exception { 4 5 // 獲得類對象 6 Class<?> clazz = Class.forName("com.gerrard.create.method_newInstance.ObjectToCreate"); 7 // 類對象的 newInstance() 方法,只能調用公有的無參構造器 8 clazz.newInstance(); 9 10 // 獲得構造器對象數組(無論是私有仍是公有的構造器) 11 Constructor<?>[] cons = clazz.getDeclaredConstructors(); 12 cons[1].newInstance(); 13 cons[2].newInstance("Gerrard"); 14 // 先打破私有構造器不可訪問的限制 15 cons[0].setAccessible(true); 16 cons[0].newInstance("Gerrard", "Info"); 17 } 18 }
備註:orm
Object 類是全部類的直接或間接父類,Object 類中提供了 實例方法 clone(),在給定對象的基礎上,建立一個徹底相同的對象。步驟以下:對象
示例代碼:blog
1 public class ObjectToCreate implements Cloneable { 2 3 // 重寫 Object 類的 clone() 方法(native 方法) 4 public ObjectToCreate clone() { 5 ObjectToCreate obj = null; 6 try { 7 obj = (ObjectToCreate) super.clone(); 8 } catch (CloneNotSupportedException e) { 9 // 沒有實現 Cloneable 接口就會拋出這個異常 10 e.printStackTrace(); 11 } 12 return obj; 13 } 14 }
備註:接口
這個方法一共分兩步:ci
序列化:
反序列化:
示例代碼:
1 public class ObjectToCreate implements Serializable { 2 3 private static final long serialVersionUID = 1L; 4 5 private Object writeReplace(){ 6 return new Integer(1); 7 } 8 9 private Object readResolve(){ 10 return new Double(2); 11 } 12 }
1 public class MethodSerialable { 2 3 public static void main(String[] args) { 4 5 // 默認路徑是項目的根路徑 6 final String fileName = "./file/serialable.txt"; 7 8 ObjectToCreate o1 = new ObjectToCreate(); 9 10 // 序列化 11 try (FileOutputStream fos = new FileOutputStream(fileName); 12 ObjectOutputStream oos = new ObjectOutputStream(fos);) { 13 oos.writeObject(o1); 14 } catch (FileNotFoundException e) { 15 e.printStackTrace(); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 } 20 }
1 public class MethodAntiSerialable { 2 3 public static void main(String[] args) { 4 // 默認路徑是項目的根路徑 5 final String fileName = "./file/serialable.txt"; 6 Object o2 = null; 7 // 反序列化 8 try (FileInputStream fio = new FileInputStream(fileName); ObjectInputStream ois = new ObjectInputStream(fio);) { 9 o2 = ois.readObject(); 10 } catch (FileNotFoundException e) { 11 e.printStackTrace(); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } catch (ClassNotFoundException e) { 15 e.printStackTrace(); 16 } 17 System.out.println(o2); 18 } 19 }
備註:
Java 建立對象的4種方法:第一種是最經常使用的;第二種方法深刻至源碼會指向 sun.reflect.ConstructorAccessor 類,JDK 中彷佛沒有提供繼續深刻下去的源碼,可是既然是調用構造器的方法,那麼與第一種方法同樣,建立的對象是存儲在堆(Heap)中的;第三種方法是要實現特定的接口才可使用,並且是經過調用 native 方法,也就是非 Java 代碼(很大多是 C)實現的,也就是說,這個方法產生的對象,可能不會被 GC 回收(我的的想法),由於 GC 是用來回收 Java 代碼創造的對象,因此要慎用;第四種方法在序列化的時候,須要實現特定的接口,而在反序列化時就不關心這一點了,它是將對象暫存於其餘媒介中,在反序列化的時候將對象存於堆中。