反射機制
– 指的是能夠於運行時加載、探知、使用編譯期間徹底未知的類。
– 程序在運行狀態中,能夠動態加載一個只有名稱的類,對於任意一個已加載的類,都可以知道這個類的全部屬性和方法;
對於任意一個對象,都可以調用它的任意一個方法和屬性;
Class c = Class.forName("com.bjsxt.test.User");
– 加載完類以後,在堆內存中,就產生了一個 Class 類型的對象(一個類只有一個 Class 對象),這個對象就包含了完整的類的結構信息。
咱們能夠經過這個對象看到類的結構。這個對象就像一面鏡子,透過這個鏡子看到類的結構,因此,咱們形象的稱之爲:反射。
Class類
java.lang.Class類十分特殊,用來表示java中類型(class/interface/enum/annotation/primitive type/void)自己。
– Class類的對象包含了某個被加載類的結構。一個被加載的類對應一個Class對象。
– 當一個class被加載,或當加載器(class loader)的defineClass()被JVM調用,JVM 便自動產生一個Class 對象。
Class類是Reflection的根源。
– 針對任何您想動態加載、運行的類,惟有先得到相應的Class 對象
Class對象的獲取:
運用getClass()
運用Class.forName()(最常被使用)
運用.class 語法
反射機制的做用:
• 動態加載類、動態獲取類的信息(屬性、方法、構造器)
• 動態構造對象
• 動態調用類和對象的任意方法、構造器
• 動態調用和處理屬性
• 獲取泛型信息
• 處理註解
反射操做泛型(Generic)
• Java採用泛型擦除的機制來引入泛型。Java中的泛型僅僅是給編譯器javac使用的,確保數據 的安全性和免去強制類型轉換的麻煩。
可是,一旦編譯完成,全部的和泛型有關的類型所有 擦除。 • 爲了經過反射操做這些類型以迎合實際開發的須要,Java就新增了
ParameterizedType, GenericArrayType,TypeVariable 和WildcardType幾種類型來表明不能被歸一到Class 類中的類型但
是又和原始類型齊名的類型。
• ParameterizedType: 表示一種參數化的類型,好比Collection<String>
• GenericArrayType: 表示一種元素類型是參數化類型或者類型變量的數組類型
• TypeVariable: 是各類類型變量的公共父接口
• WildcardType: 表明一種通配符類型表達式,好比?, ? extends Number, ? super Integer【 wildcard是一個單詞:就是「通配符」】
反射操做註解(Annotation)
能夠經過反射API:getAnnotations, getAnnotation得到相關的註解信息java
//得到類的全部有效註解
Annotation[] annotations=clazz.getAnnotations(); for (Annotation a : annotations) { System.out.println(a); } //得到類的指定的註解
SxtTable st = (SxtTable) clazz.getAnnotation(SxtTable.class); System.out.println(st.value()); //得到類的屬性的註解
Field f = clazz.getDeclaredField("studentName"); SxtField sxtField = f.getAnnotation(SxtField.class); System.out.println(sxtField.columnName()+"--"+sxtField.type()+"--"+sxtField.length());
反射機制性能問題
• setAccessible
– 啓用和禁用訪問安全檢查的開關,值爲 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查。
值爲 false 則指示反射的對象應該實施 Java 語言訪問檢查。並非爲true就能訪問爲false就不能訪問。
– 禁止安全檢查,能夠提升反射的運行速度。
• 能夠考慮使用:cglib/javaassist字節碼操做</