Java 是面向對象的語言,不可避免的,“對象”這個概念是 Java 語言的核心部分,這裡來簡單討論一下在 Java 中創建一般對象的方法。
總結下來有以下4種創建對象的方法:
最常見的 Java 對象的構造方法,通過調用類提供的構造器創建對象。
Java 反射中有一個 newInstance() 方法,可以創建對象,步驟如下:
示例代碼:

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 }
MethodNewInstance
備注:
Object 類是所有類的直接或間接父類,Object 類中提供了 實例方法 native(),在給定對象的基礎上,創建一個完全相同的對象。步驟如下:
示例代碼:

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 }
ObjectToCreate
備注:
這個方法一共分兩步:
序列化:
反序列化:
示例代碼:

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 }
ObjectToCreate

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 }
MethodSerialable

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 }
MethodAntiSerialable
備注:
Java 創建對象的4種方法:第一種是最常用的;第二種方法深入至源碼會指向 sun.reflect.ConstructorAccessor 類,JDK 中似乎沒有提供繼續深入下去的源碼,但是既然是調用構造器的方法,那麼與第一種方法一樣,創建的對象是存儲在堆(Heap)中的;第三種方法是要實現特定的接口才可以使用,而且是通過調用 native 方法,也就是非 Java 代碼(很大可能是 C)實現的,也就是說,這個方法產生的對象,可能不會被 GC 回收(個人的想法),因為 GC 是用來回收 Java 代碼創造的對象,所以要慎用;第四種方法在序列化的時候,需要實現特定的接口,而在反序列化時就不關心這一點了,它是將對象暫存於其他媒介中,在反序列化的時候將對象存於堆中。