反射功能-学习笔记
2019獨角獸企業重金招聘Python工程師標準>>>
/*** 反射測試* java.lang.Class ---- 類的創建* java.lang.reflect.Constructor ----- 反射類中構造方法* java.lang.reflect.Field ----- 反射屬性* java.lang.reflect.Method ----- 反射方法* java.lang.reflect.Modifier ----- 訪問修飾符的信息* <p>* 實現反射,實際上是得到Class對象,使用java.lang.Class這個類。* 這是Java發射機制的起源,當一個類被加載后,Java虛擬機會自動產生一個Class對象*/private void doReflect() throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//獲取Class對象的方法//1.try {Class clz1 = Class.forName("iandroid.club.bblogs.TestRouterActivity");} catch (ClassNotFoundException e) {e.printStackTrace();}//2.Class clz2 = TestRouterActivity.class;//3.getClass獲取Class clz3 = new TestRouterActivity().getClass();/*** 三種方法的區別:* 1.會讓ClassLoader裝載類,并進行類的初始化* 2.返回類對象運行時真正所指的對象/所屬類型的Class對象* 3.ClassLoader裝載入內存,不對類進行類的初始化操作* 區分重點在于,是否進行初始化 和 是否在實例中獲取*//*** 1.forName中的參數需要填入全路徑類名,* 但是只能創建無參數對象*/try {Class clz = Class.forName("");Object o = clz.newInstance();} catch (Exception e) {e.printStackTrace();}/*** 2.有參數創建對象* 返回一個Constructor對象,反映了此Class對象所表示的類指定的公共構造方法*/Constructor<?> csr = clz2.getConstructor(String.class, int.class);Object o = csr.newInstance("gabriel", 20);/*** 反射類中的屬性需要使用Field對象*/Field field = clz2.getDeclaredField("name");//使用setAccessible取消封裝,特別是可以取消私有字段訪問限制field.setAccessible(true);// 設置o 對象field.set(o, "hello");/*** Field類描述的是屬性對象,其中可以獲取到很多屬性的信息,包括名字/屬性類型/屬性的注解** 在安全管理器中會使用checkPermission方法來檢查權限,* 而setAccessible(true)并不是將方法的權限改為public,而是取消java的權限控制檢查,* 所以即使是public方法,qiaccessible屬性默認也是false*//*獲取修飾符*/String priv = Modifier.toString(field.getModifiers());/*獲取類中的方法getDeclaredMethod 獲取的是類自身聲明的所有方法,包含public/protected和private方法*/Method m = clz2.getDeclaredMethod("setName", String.class);/*通用反射調用方法Method中的invoke方法用于檢查 AccessibleObject 的override屬性是否為trueAccessibleObject是Method/Field/Constructor的父類,override屬性默認為false,可以調用setAccessible方法改變,如果設置為true,則表示可以忽略訪問權限的限制,直接調用。*/m.invoke(clz2, "hello");/*** java 的反射機制提供了動態代理模式實現*/RealSubject realSubject = new RealSubject();Subject proxySubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),new Class[]{Subject.class},new ProxyHandler(realSubject));proxySubject.doSomething();//動態代理的作用在于 不修改源碼的情況下,可以增強一些方法,在方法的執行前后做些想做的事情}public interface Subject{public void doSomething();}public class RealSubject implements Subject{@Overridepublic void doSomething() {}}public class ProxyHandler implements InvocationHandler{private Object realSubject;public ProxyHandler(Object realSubject) {this.realSubject = realSubject;}@Overridepublic Object invoke(Object o, Method method, Object[] objects) {//在轉調具體目標對象之前,可以執行一些功能處理//調用具體目標對象方法Object result = null;try {result = method.invoke(realSubject, objects);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return result;}}?
轉載于:https://my.oschina.net/gabriel1215/blog/1808270
總結
- 上一篇: Redis入门(暂不更新)
- 下一篇: 容易被误读的IOSTAT