前言:
最近在看springIOC和AOP是看見代碼中很實用newInstance來實例化一個對象,之前對newInstance和new實例化對象的區別很模糊,特意在這里記錄一下
一、newInstance()和new()區別:
1、兩者創建對象的方式不同,前者是實用類的加載機制,后者則是直接創建一個類:
2、newInstance創建類是這個類必須已經加載過且已經連接,new創建類是則不需要這個類加載過
3、newInstance: 弱類型(GC是回收對象的限制條件很低,容易被回收)、低效率、只能調用無參構造,new 強類型(GC不會自動回收,只有所有的指向對象的引用被移除是才會被回收,若對象生命周期已經結束,但引用沒有被移除,經常會出現內存溢出)
二、伸縮、擴展性:
在開發中,我們經常可以看到一些接口的設計,實現接口的類加載一般都會采用newInstance而不會使用new,在這里就涉及到了兩者在開發過程中的擴展性和伸縮性,來看一段代碼:
定義一個BeanFactory接口,分別讓類A、B實現接口:
package com.main; public interface BeanFactory { //核心方法getBean Object getBean(String name); }
public class B implements BeanFactory{ @Override public Object getBean(String name) { return null; } }
public class A implements BeanFactory{ @Override public Object getBean(String name) { return null; } }
測試結果:
public class Test { @SuppressWarnings("rawtypes") public static void main(String[] args) throws Exception { Class a1 = Class.forName("A"); BeanFactory a2 = (BeanFactory) a1.newInstance(); System.out.println(a2); Class b1 = Class.forName("B"); BeanFactory b2 = (BeanFactory) b1.newInstance(); System.out.println(b2); } }
A@15db9742
B@6d06d69c
通過上面實例我們可以很清楚的看到,如果在接口的設計中很多類實現了該接口,我們只需要使用Class中的forName方法加載一下類就可以了,可以將這一段代碼提出來作為一個工具類方法,不管有多少類只要實現了該接口我們只要傳入需要實例化的路徑名就可以實例化,這樣大大節省了我們的代碼(注:newInstance實例化對象是只能調用無參構造方法,在A、B類中並沒有構造方法,是因為每個創建的類都有一個默認的無參構造方法,如果你重寫了一個帶參構造方法,想要使用newInstance,則必須指定一個無參構造方法,否則會報初始化錯誤)