【參考資料: 瘋狂Java講義 Chapter 18】java
一、類加載、鏈接、初始化數組
當Java程序須要某一個類時,若是該類還沒有加載到內存中,系統會經過加載、鏈接、初始化三個步驟將該類加載到內存,並完成初始化工做。函數
二、類加載器spa
JVM啓動時,會造成由三個類加載器類組成的初始類的加載器層次結構:code
三個類加載器之間的層次關係:component
三、經過反射操做類對象
1)獲取java.lang.Class對象的經常使用方式blog
2)Class類提供的接口繼承
獲取Class對象所對應類的構造器的接口:接口
1 Constructor<T> getConstructor(Class<?>... parameterTypes) //返回對應該類的public的構造器,構造器參數列表的類型聲明次序符合parameterTypes類型聲明次序,被封裝成了Constructor對象 2 Constructor<?>[] getConstructors() //獲取全部public構造器 3 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) //返回對應parameterTypes類型聲明次序的該類的構造器,與訪問級別無關 4 Constructor<?>[] getDeclaredConstructors()//返回全部的構造器,與訪問級別無關
5 Constructor<?> getEnclosingConstructor() //用於匿名類或內部類
獲取Class對象對應類的方法的接口:
1 Method getMethod(String name, Class<?>... parameterTypes); //返回由方法名name和參數列表類型parameterTypes限定的public方法 2 Method[] getMethods(); //全部public方法 3 Method getDeclaredMethod(String name, Class<?>... parameterTypes); //返回由方法名和參數列表類型parameterTypes限定的方法,與訪問級別無關 4 Method[] getDeclaredMethods(); //全部方法
5 Method getEnclosingMethod(); //用於獲取內部類或匿名類的方法
獲取Class對象對應類所包含的屬性的接口:
1 Field getField(String name); //返回對應name的public 屬性 2 Field[] getFields(); //全部public屬性 3 Field getDeclaredField(String name); 4 Field[] getDeclaredFields();
【注:方法名中帶有Declared的方法返回的構造器、方法或屬性等都是忽略訪問級別的;而不帶有Declared的方法返回public的類成員。】
訪問Class對應類的註釋的接口:
1 <A extends Annotation> A getAnnotation(Class<A> annotationClass); //返回符合特定註解類型annotationClass的註解 2 Annotation[] getAnnotations(); //當前Class的全部註解 3 Annotation[] getDeclaredAnnotations(); //直接出如今當前元素上的註解
Class中用於判斷該Class是否爲註釋類型、數組類型、接口類型的接口:
1 boolean isAnnotation(); 2 boolean isAnnotationPresent(Class<? extends Annotation> annotationClass); //判斷是否出現了特定類型的註解 3 boolean isAnonymousClass(); 4 boolean isArray(); 5 boolean isEnum(); 6 boolean isInstance(Object obj); //判斷obj類型是否與當前Class對應的類型兼容 7 boolean isInterface(); 8 boolean isLocalClass(); 9 boolean isPrimitive();
其餘接口:
1 String getName();//返回該Class表明的類或接口的全稱 2 String getPackage(); //返回包名 3 String getSimpleName(); //Class對應類的簡稱 4 Class<? super T> getSuperclass(); //返回超類
對於上述接口中出現的Class<?>... parameterTypes,是指定的參數列表的Class對象。如:
1 public class ReflectionTest{ 2 3 private int privateAttribute = -1; 4 public int publicAttribute = -2; 5 6 public String publicStrAttribute = "DefaultString"; 7 8 9 public void info(){ 10 System.out.println("This is info() of class ReflectionTest"); 11 } 12 13 public void info(String str){ 14 System.out.println("This is info(String) of class ReflectionTest"); 15 } 16 17 public void info(String str, Integer num){ 18 System.out.println("This is info(String, Integer) of class ReflectionTest"); 19 } 20 21 private void privateInfo(){ 22 System.out.println("This is privateInfo method"); 23 } 24 25 public static void main(String[] args) throws Exception{ 26 Class<ReflectionTest> testClass = ReflectionTest.class; 27 28 Method info1 = testClass.getMethod("info", null); 29 System.out.println("方法參數列表長度: "+info1.getParameterTypes().length); 30 31 Method info2 = testClass.getMethod("info", String.class); 32 System.out.println("方法參數列表長度: "+info2.getParameterTypes().length); 33 34 Method info3 = testClass.getMethod("info", String.class, Integer.class); 35 System.out.println("方法參數列表長度: "+info3.getParameterTypes().length); 36 } 37 }
3)經過反射生成並操做對象
1 Class<ReflectionTest> testClass = ReflectionTest.class; 2 3 //經過Class對象構造Class對應類的實例 4 ReflectionTest rt1 = testClass.newInstance(); 5 Constructor constructor = testClass.getConstructor(null); 6 ReflectionTest rt2 = (ReflectionTest)constructor.newInstance(null); //調用默認構造函數,參數列表爲空
【注:代碼基於ReflectionTest類】
4)調用方法
1 Object newTest = constructor.newInstance(null); 2 Method info = testClass.getMethod("info", null); 3 info.invoke(newTest, null);
而後調用private方法:
1 Method privateMethod = testClass.getDeclaredMethod("privateInfo", null); //獲取private方法使用getDeclaredMethod方法 2 privateMethod.setAccessible(true); 3 privateMethod.invoke(newTest, null);
5)操做屬性值
1 //操做屬性 2 Field privateField = testClass.getDeclaredField("privateAttribute"); //私有屬性 3 System.out.println(privateField.getInt(newTest)); 4 privateField.setInt(newTest, -1000); 5 System.out.println(privateField.get(newTest)); 6 7 Field strField = testClass.getField("publicStrAttribute"); //公有屬性 8 System.out.println(strField.get(newTest)); 9 strField.set(newTest, "test value"); 10 System.out.println(strField.get(newTest));
6)操做數組
java.lang.reflect包下含有Array類,Array類提供了能夠動態建立和訪問Java數組的靜態方法。
主要接口:
1 static static Object newInstance(Class<?> componentType, int... dimensions); //多維度的數組 2 static Object newInstance(Class<?> componentType, int length); //指定數組長度的數組 3 4 static XXX getXXX(Object array, int index); //對於8中基本類型 5 static void setXXX(Object array, int index, XXX newValue); 6 7 static Object get(Object array, int index); //對於引用類型 8 static void setXXX(Object array, int index, Object newValue);