1、反射機制
反射機制允許程序在執行的過程中通過Reflection API獲取任意一個類的內部信息,並能夠操作它的屬性及方法。
2、反射的簡單認識
2.1 通過反射生成對象的實例(簡單Java類Person)
Class personClass = Person.class //創建運行時類的對象
Person person = (Person)personClass.newInstance(); //創建Person對象的實例
2.2 通過反射生成實例並調用對象屬性
*調用公有的屬性
Filed name = personClass.getField("name"); // 獲取public類型屬性
name.set("zy");
*調用私有的屬性
此時如果使用getField()調用報異常java.lang.NoSuchFieldException: name
如果沒有name.setAccessiable(true)報異 訪問權限非法常java.lang.IllegalAccessException:
Filed name = personClass.getDeclaredField("name"); //獲取私有屬性
name.setAccessiable(true); //將該屬性設置爲可訪問的
name.set(person,"zy");
2.2 通過反射的生成實例並調用對象的方法
Method methodName = personClass.getMethod("MethodName"); //獲取方法名爲MethodName方法,沒有帶參數
methodName.invoke(person);
Method methodName = personClass.getMethod("MethodName",String.class); //帶參數
methodName.invoke(person,"computer");
3、Class是反射的源頭
3.1 反射機制
3.2 關於Class
一個.java類,通過javac.exe生成.class文件,然後通過java.exe將此.class文件加載(使用JVM類加載器)到內存中,此時這個被加載到內存中的.class文件就是一個運行時類。而這個運行時類本身就是一個Class的對象。每個運行時類只加載一次
3.3 創建Class類實例的方法(4種)
3.3.1 通過運行時類本身創建Class類的實例,調用class屬性
Class personClass = Person.class;
3.3.2
通過運行時類的引用調用getClass()方法
Person person = new Person();
Class personClass = person.getClass();
3.3.2
通過Class類的靜態方法forName()
String className = "com.relection.domain.Person";
Class personClass = Class.forName(className ); //動態的創建對象,可以根據用戶傳來的類名進行創建
Person person = (Person)personClass.newInstance();//創建Person的實例
3.3.4
通過類的加載器
ClassLoader classLoader = this.getClass().getClassLoader();
Class personClass4 = classLoader.loadClass("com.relection.domain.Person");
Person person2 = (Person) personClass4.newInstance();
4、類的加載器
類的加載器用來把類(class)加載進內存中。
java類的加載過程
java虛擬機的類加載器的種類
引導類加載器,用來加載核心類庫,無法直接獲取
擴展類加載器
系統類加載器
5、類加載器讀取文件
ClassLoader loader = this.getClass().getClassLoader();
InputStream is = loader.getResourceAsStream("info.properties");
Properties p = new Properties();
p.load(is);
String userName = p.getProperty("username");
String password = p.getProperty("password");
6、通過類的反射獲取類本身的信息
6.1
獲取類的方法
6.2 獲取類的屬性及其權限
6.3 獲取類的父類
6.4 獲取已經實現的接口
6.5 獲取父類的泛型
6.6 獲取類的註解
7.反射的應用
7.1 Dao工廠
7.2 動態代理
代理類要實現InvocationHandler接口
public class QualityHandler implements InvocationHandler {
Object target; //聲明被代理類對象的引用
public QualityHandler(Object obj){
target = obj;
}
public Object createProxy(Object target){
//此類加載器需要和目標對象的相同
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object object = method.invoke(target, args);
System.out.println("服裝質量安全檢查");
return object;
}
}