- Java Reflection
- 反射是動態(tài)語言實現(xiàn)的關鍵
- 發(fā)射機制允許在執(zhí)行期間借助Reflection API取得任何類的內部信息齐婴,
并直接操作任意對象的內部屬性及方法
- Java反射機制提供的功能
- 在運行時候判斷任意一個對象所屬的類
- 在運行時構造任意一個類的對象
- 在運行時判斷任意一個類所具有的成員變量和方法
- 在運行時調用任意一個對象的成員變量和方法
- 生成動態(tài)代理
- 如何創(chuàng)建Class的實例(重點)
/** * java.lang.Class:是反射的源頭 * 我們創(chuàng)建了一個類,通過編譯舔痪,生成對應的.class文件胜卤, * 之后使用java.exe加載此文件(JVM的類加載器完成) * 此文件加載到內存以后户魏,就是一個運行時類,存放在緩存區(qū) * 那么該運行時類本身就是一個大的Class的實例 */ //1.調用運行時類本身的.Class屬性 Class c1 = Person.class; //2. 通過運行時類的對象獲取 Person p = new Person(); Class c3 = p.getClass(); //3.通過Class的靜態(tài)方法獲取 String class_name = "learning_reflect.Person"; Class c4 = Class.forName(class_name); //4.通過類的加載器 ClassLoader cl = this.getClass().getClassLoader(); Class c5 = cl.loadClass(class_name);
- 有了Class類實例之后闲孤,可以做什么?
- 從Class類實例烤礁,創(chuàng)建運行時類的對象
//方法一讼积,調用Class類的newInstance方法,直接創(chuàng)建運行時對象 Class clazz = Class.forname("learning_reflect.Person"); Object obj = clazz.newInstance(); Person p = (Person) obj; //方法二脚仔,調用指定的構造器,創(chuàng)建運行時對象 Class clazz = Person.Class; Constructor cons = clazz.getDeclaredConstructor(String.Class,int.Class); cons.setAccessible(true); Person p = (Person)cons.newInstance("Tom", 10);
- 獲取對應的運行時類的完整類結構:屬性勤众、方法、構造器鲤脏、所在包们颜、父類、接口猎醇、
泛型窥突、注解、異常硫嘶、內部類
//舉例如下 //getMethods方法獲取運行時類及其父類中所有聲明為public的方法 Method[] m1 = clazz.getMethods(); //getDeclaredMethods方法獲取運行時類自身聲明的所有方法,但不包含父類的 Method[] m2 = clazz.getDeclaredMethods();
- 可以調用運行時類中指定的結構(方法阻问、屬性、構造器等)
//調用指定非靜態(tài)方法 Class clazz = Person.class; Method m1 = clazz.getMethod("show"); Person p = (Person) clazz.newInstance(); Object returnValue = m1.invoke(p);//This is a person //調用指定靜態(tài)方法 Method m3 = clazz.getMethod("info"); m3.invoke(Person.class); //調用指定構造器 String classname = "learning_reflect.Person"; Class clazz = Class.forName(classname); Constructor cons = clazz.getDeclaredConstructor(String.class, int.class); cons.setAccessible(true); Person p = (Person) cons.newInstance("羅維", 20);
- 動態(tài)代理-反射的應用沦疾,體會反射的動態(tài)性
- 代理設計模式的原理:
- 使用一個代理將對象包裝起來称近,然后用該代理取代原始對象第队,
任何對原始對象的調用都要通過代理,
代理決定是否以及何時將方法調用轉移到原始對象上刨秆。 - 靜態(tài)代理:要求被代理類和代理類同時實現(xiàn)相應的一組接口凳谦;
通過代理類的對象調用重寫接口的方法時,實際上執(zhí)行的是被代理類的同樣的方法衡未。 - 動態(tài)代理:在程序運行時晾蜘,根據(jù)被代理類及其實現(xiàn)的接口,動態(tài)的創(chuàng)建一個代理類眠屎,
當調用代理類的實現(xiàn)的抽象方法時剔交,就發(fā)起對被代理類同樣方法的調用。- 提供一個實現(xiàn)了InvocationHandler接口實現(xiàn)類改衩,并重寫其invoke方法
- Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),h);
(此處obj為被代理類對象岖常,h為實現(xiàn)了InvocationHandler的一個對象)
- 使用一個代理將對象包裝起來称近,然后用該代理取代原始對象第队,
- 動態(tài)代理與AOP
package learning_reflect; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface Human { void info(); void fly(); } class SuperMan implements Human { @Override public void fly() { System.out.println("Here comes Clerk"); } @Override public void info() { System.out.println("I am Super Man"); } } class HumanUtil { public void method1() { System.out.println("===方法一==="); } public void method2() { System.out.println("===方法二==="); } } class SelfInvocationHandler implements InvocationHandler { Object obj;//被代理對象的聲明 public void setObject(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { HumanUtil h = new HumanUtil(); h.method1(); Object returnVal = method.invoke(obj, args); h.method2(); return returnVal; } } class MyProxy { //動態(tài)地創(chuàng)建一個代理類的對象 public static Object getProxyInstance(Object obj) { SelfInvocationHandler handler = new SelfInvocationHandler(); handler.setObject(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler); } } public class TestAOP { public static void main(String[] args) { SuperMan man = new SuperMan(); Object obj = MyProxy.getProxyInstance(man); Human sm = (Human) obj; sm.info(); System.out.println(); sm.fly(); } }
JavaSE學習筆記——反射
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
- 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姊氓,“玉大人丐怯,你說我怎么就攤上這事∠韬幔” “怎么了读跷?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長禾唁。 經(jīng)常有香客問我效览,道長,這世上最難降的妖魔是什么荡短? 我笑而不...
- 文/花漫 我一把揭開白布沼本。 她就那樣靜靜地躺著噩峦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抽兆。 梳的紋絲不亂的頭發(fā)上识补,一...
- 文/蒼蘭香墨 我猛地睜開眼名惩,長吁一口氣:“原來是場噩夢啊……” “哼澎胡!你這毒婦竟也來了?” 一聲冷哼從身側響起娩鹉,我...
- 正文 年R本政府宣布糟趾,位于F島的核電站慌植,受9級特大地震影響,放射性物質發(fā)生泄漏义郑。R本人自食惡果不足惜蝶柿,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望非驮。 院中可真熱鬧交汤,春花似錦、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至戒洼,卻和暖如春俏橘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背圈浇。 一陣腳步聲響...
推薦閱讀更多精彩內容
- 一:java概述:1,JDK:Java Development Kit妓灌,java的開發(fā)和運行環(huán)境轨蛤,java的開發(fā)工...
- Java是一種可以撰寫跨平臺應用軟件的面向對象的程序設計語言。Java 技術具有卓越的通用性虫埂、高效性祥山、平臺移植性和...
- 反射 類的加載概述 程序要使用某個類缝呕,如果類還未加載到內存中,系統(tǒng)會通過加載斧散,連接供常,初始化來實現(xiàn)對這個類進行初始化...