Java反射基礎認識
[送書] 反射中特別容易忽略的幾個近似方法相關筆試題解析
//
反射的初步認識
Java中的反射機制是指在執行狀態中,對於任意一個類,都可以知道這個類的所有屬性和方法。對於一個任意的Java物件,在執行時的都可以獲取其類的資訊,包括部分編譯時不能獲取的類資訊。反射是基於在執行時類都會被類載入器ClassLoader動態載入,當ClassLoader將一個目標類載入後JVM中創建出一個Class物件,這個物件中包含這個類的所有資訊。即Class類是反射機制的起源和載體。
反射顯著作用:
反編譯:class —> .java[網上書上都這麼說個人沒搞過];
反射訪問Java物件中的屬性、函式、建構函式等;
反射的最大好處個人認為提高程式碼靈活度、健壯性,節省大量臃腫的程式碼;
反射中使用到的類:
java.lang.Class ————>類物件的建立;
java.lang.reflect.Constructor————>反射獲取Java物件中的構造器;
java.lang.reflect.Field————>反射獲取Java物件中的變數;
java.lang.reflect.Method————>反射獲取Java物件中的函式;
java.lang.reflect.Modifier————>反射獲取Java物件中的修飾限定符[public/private];
Java中獲取Class的三種方式:
1.通過類名獲得,Java中每個型別都有Class屬性;
Class<?> aClass= ClassName.class;
2.通過類名的全路徑獲得,Java中Class類中的都有的靜態函式:
public static Class<?> forName(String className);
Class<?> aClass=Class.forName("com.java.maskClassName");
3.通過例項物件獲得,Java的Object類中提供的public final Class<?> getClass(),不過很顯然需要先有類的物件;
Class<?> aClass= new maskObject().getClass();
1、獲取Class物件的三種方式
1.1 Java的Object提供一個方法 getClass(),返回一個class物件
1.2 任何資料型別(包括基本資料型別)都有一個“靜態”的class屬性
1.3 通過Class類的靜態方法:forName(String className)(常用)
1.4 new 方式獲取物件
2、通過反射獲取構造方法並使用:
問:簡單說說下面獲取類的 Class 物件區別?
Class c1 = Class.forName(“cn.test.Demo”);
Class c2 = Demo.class;
Class c3 = new Demo().getClass();
答:上面程式碼段都是獲取 Class 例項,區別如下解釋(具體可以檢視原始碼)。
c1 方式會讓 ClassLoader 進行類載入然後進行類的初始化。
c2 方式會讓 ClassLoader 進行類載入但是不初始化。
c3 方式獲取的是已經被載入且初始化過後例項化執行中類的 Class 例項。
問:簡單說說 Java 反射各種獲取 Field 方法的區別?
答:簡單說就是 getField(s) 返回的是申明為 public 的屬性,包括指定類和其父類中定義的;而 getDeclaredField(s) 返回的是指定類中定義的所有屬性,不包括父類的,如果想獲取父類的需要首先通過指定類的 getSuperclass() 獲取其父類然後再呼叫 getDeclaredField(s) 獲取。詳細區別如下:
//返回一個 Field 物件,只能獲取當前類或者其父類指定的 public 成員。
public Field getField(String name)
//返回一個 Field 物件陣列,只能獲取當前類或者其父類所有 public 成員。
public Field[] getFields()
//返回一個 Field 物件,只能返回當前類指定的所有型別成員(public、procted、private)。
public Field getDeclaredField(String name)
//返回一個 Field 物件陣列,只能返回當前類指所有型別成員(public、procted、private)。
public Field[] getDeclaredFields()
問:簡單說說 Java 反射各種獲取 Method 方法的區別?
答:答案與原理策略完全類似上面 Field 的解釋,只需要將 getMethod(s) 與 getField(s) 對應,getDeclaredMethod(s) 與 getDeclaredField(s) 對應理解即可。
問:簡單說說 Java 反射各種獲取類 Constructor 的方法區別?
答:反射的構造方法是無法獲取父類的任何構造方法的,一定要明確這一點,其他詳細區別如下解釋。
//返回一個 Constructor 物件,代表指定類的指定 public 構造方法。
public Constructor getConstructor(Class<?>… parameterTypes)
//返回一個 Constructor 物件陣列,代表指定類的所有 public 構造方法。
public Constructor<?>[] getConstructors()
//返回一個 Constructor 物件,代表指定類的指定構造方法(不限制修飾符)。
public Constructor getDeclaredConstructor(Class<?>… parameterTypes)
//返回一個 Constructor 物件陣列,代表指定類的所有構造方法(不限制修飾符)。
public Constructor<?>[] getDeclaredConstructors()
問:簡單說說 Java Class.newInstance() 與 Constructor.newInstance() 方法區別?
答:呼叫 Class 物件的 newInstance 方法會呼叫物件的預設構造方法,如果沒有預設構造方法就會異常呼叫失敗。而呼叫 Constructor 物件的 newInstance 方法可以選擇要不要傳遞引數,沒有引數時就類似 Class 的 newInstance,有引數時就呼叫對應有參構造方法