反射指動態(tài)獲取類及類中的內(nèi)容
示例代碼:String className = "cn.itheima.web.servlet.MyServletImpl"; ? ? ? ? ? ? ? ? ? ? Class clazz = Class.forName(className); ? ? ? ? ? ? ? ? ? ? MyServletImpl my = (MyServletImpl) clazz.newInstance();
?
如何獲取類的Class對象(字節(jié)碼文件)?
1,通過Object類的getClass() 方法 ,需要先創(chuàng)建對象 ? ? ? -----比較兩個文件是否為同一個字節(jié)碼文件
2,通過Class的靜態(tài)屬性 ?? .class? 獲取 ? ? -----鎖對象
3,通過Class的靜態(tài)方法,Class.forName( )方法獲取 ? ----讀取配置文件
如何獲取Class對象所對應(yīng)的類的構(gòu)造方法?
1,無參構(gòu)造,可以直接用newInstance( )來創(chuàng)建對象
2,有參構(gòu)造,可以用 getConstructor( )來獲取構(gòu)造方法,(括號里不傳入?yún)?shù)是獲取無參構(gòu)造方法,傳入?yún)?shù)是獲取有參構(gòu)造)再使用newInstance( )來創(chuàng)建對象
代碼演示如下:
Class clazz = Class.forName("Bean.Person"); //獲取Person類的Classd對象
Constructor constructor = clazz.getConstructor(String.class, int.class); //(反射階段) 獲取有參構(gòu)造,不傳入?yún)?shù)則是獲取無參構(gòu)造
Person p = (Person) constructor.newInstance("張三", 23); // 根據(jù)有參構(gòu)造創(chuàng)建實例
System.out.println(p);
如何獲取Class對象所對應(yīng)的類或接口的定義的變量,字段?
1,如是公共變量,可以在獲取Class對象后,調(diào)用getField(String ?)獲取
2,如是私有變量,可以在獲取Class對象后,調(diào)用getDeclaredField(Sting ?)暴力獲取 聲明的變量,如需改變其值,則需用,setAccessible(ture)去除私有權(quán)限
Class clazz = Class.forName("Bean.Person"); //獲取Person類的Classd對象
Constructor constructor = clazz.getConstructor(String.class, int.class);
Person p = (Person) constructor.newInstance("張三", 23); // 根據(jù)有參構(gòu)造創(chuàng)建實例
//Field field = clazz.getField("name"); //獲取公共變量
Field declaredField = clazz.getDeclaredField("name");
declaredField.setAccessible(true);//去除私有屬性
declaredField.set(p, "李四");
System.out.println(p);
如何獲取Class對象對應(yīng)的類或接口中的方法?
1,公共方法,getMethod( )
2,私有方法,getDeclaredMethod( )
Class clazz = Class.forName("Bean.Person"); //獲取Person類的Classd對象
Object p = clazz.newInstance();
Method method = clazz.getMethod("play",int.class);//反射階段
method.invoke(p, 5);
通過反射越過泛型檢查:?
package Reflect;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.omg.CORBA.INTERNAL;
public class demo6_test1 {
// 通過反射越過越過泛型檢查(泛型檢擦只在編譯器,在運行期,反射階段可以跳過檢查)
public static void main(String[] args) throws Exception {
ArrayList<Integer> al = new ArrayList<>();
al.add(11);
Class<?> clazz = Class.forName("java.util.ArrayList");
Method method = clazz.getDeclaredMethod("add", Object.class);// ArrayList類里的add方法里的原有的參數(shù)類型是Object
method.invoke(al, "abc");
System.out.println(al);
}
}
注意:?我印象中記得不能通過反射獲取父類中的私有方法,要獲取需要遞歸通過getSuperClass()獲取父類字節(jié)碼,參考這篇博文來源:http://www./content-1-249201.html
|