Java反射機制及原理
阿新 • • 發佈:2018-12-10
一、概念
java程式執行時動態的建立類並呼叫類的方法和屬性
二、原理簡介
反射的原理之一:就是動態的生成類似於上述的位元組碼,載入到JVM中執行
獲取Method物件流程
上面的Class物件是在載入類時由JVM構造的,JVM為每個類管理一個獨一無二的CLASS物件,這份CLASS物件裡維護著該類的所有
Method,Field,Constructor的cache,這份cache也可以稱作為根物件。每次getMethod獲取到的Method物件都持有對根物件的引用,因為一些重量級的Method的成員變數(主要是MethodAccessor),我們不希望每次建立Method物件都要重新初始化,於是所有代表同一個方法的Method物件都共享著根物件的MethodAccessor,每一次建立都會呼叫根物件的copy方法複製一份:
呼叫invoke方法流程
method.invoke方法會首先獲取一個MethodAccessor,首先會從Method的根物件中獲取MethodAccessor,如果為空,用reflectionFactory.newMethodAccessor返回DelegatingMethodAccessorImpl例項,然後將MethodAccessor賦值給Method的root物件中(因為MethodAccessor是所有Method共用的),然後呼叫DelegatingMethodAccessorImpl中的invoke方法,當呼叫invoke的次數大於15次以後,MethodAccessor將由java程式碼生成
整體流程圖:
Class<?> clz = Class.forName("java.util.ArrayList"); ArrayList object = (ArrayList) clz.newInstance(); Method method = clz.getMethod("add",Object.class); method.invoke(list , "sss");上面就是我們最常見的反射的例子,前兩行實現了類的裝載、連結(驗證、準備、解析)、初始化(newInstance其實也是通過反射呼叫類的<init>方法),後面兩行實現了從class物件中獲取物件然後執行反射呼叫。 設想,假如我們要實現Invoke方法,是不是隻要實現如下類即可:
public class Method { public void invoke(Object obj , Object... args) { ArrayList list = (ArrayList)obj; list.add(args); } }
Method copy() { Method res = new Method(clazz, name, parameterTypes, returnType, exceptionTypes, modifiers, slot, signature, annotations, parameterAnnotations, annotationDefault); res.root = this; res.methodAccessor = methodAccessor; return res; }