[转]Java反射机制详解
生活随笔
收集整理的這篇文章主要介紹了
[转]Java反射机制详解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
目錄
- 1反射機(jī)制是什么
- 2反射機(jī)制能做什么
- 3反射機(jī)制的相關(guān)API
- ·通過一個對象獲得完整的包名和類名
- ·實(shí)例化Class類對象
- ·獲取一個對象的父類與實(shí)現(xiàn)的接口
- ·獲取某個類中的全部構(gòu)造函數(shù) - 詳見下例
- ·通過反射機(jī)制實(shí)例化一個類的對象
- ·獲取某個類的全部屬性
- ·獲取某個類的全部方法
- ·通過反射機(jī)制調(diào)用某個類的方法
- ·通過反射機(jī)制操作某個類的屬性
- ·反射機(jī)制的動態(tài)代理
- 4反射機(jī)制的應(yīng)用實(shí)例
- ·在泛型為Integer的ArrayList中存放一個String類型的對象。
- ·通過反射取得并修改數(shù)組的信息
- ·通過反射機(jī)制修改數(shù)組的大小
- ·將反射機(jī)制應(yīng)用于工廠模式
1反射機(jī)制是什么
反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制。
2反射機(jī)制能做什么
反射機(jī)制主要提供了以下功能:?
-
在運(yùn)行時判斷任意一個對象所屬的類;
-
在運(yùn)行時構(gòu)造任意一個類的對象;
-
在運(yùn)行時判斷任意一個類所具有的成員變量和方法;
-
在運(yùn)行時調(diào)用任意一個對象的方法;
-
生成動態(tài)代理。
3反射機(jī)制的相關(guān)API
通過一個對象獲得完整的包名和類名
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 | package?net.xsoftlab.baike; public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????TestReflect?testReflect?=?new?TestReflect(); ????????System.out.println(testReflect.getClass().getName()); ????????//?結(jié)果?net.xsoftlab.baike.TestReflect ????} } |
實(shí)例化Class類對象
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package?net.xsoftlab.baike; public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????Class<?>?class1?=?null; ????????Class<?>?class2?=?null; ????????Class<?>?class3?=?null; ????????//?一般采用這種形式 ????????class1?=?Class.forName("net.xsoftlab.baike.TestReflect"); ????????class2?=?new?TestReflect().getClass(); ????????class3?=?TestReflect.class; ????????System.out.println("類名稱???"?+?class1.getName()); ????????System.out.println("類名稱???"?+?class2.getName()); ????????System.out.println("類名稱???"?+?class3.getName()); ????} } |
獲取一個對象的父類與實(shí)現(xiàn)的接口
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package?net.xsoftlab.baike; import?java.io.Serializable; public?class?TestReflect?implements?Serializable?{ ????private?static?final?long?serialVersionUID?=?-2862585049955236662L; ????public?static?void?main(String[]?args)?throws?Exception?{ ????????Class<?>?clazz?=?Class.forName("net.xsoftlab.baike.TestReflect"); ????????//?取得父類 ????????Class<?>?parentClass?=?clazz.getSuperclass(); ????????System.out.println("clazz的父類為:"?+?parentClass.getName()); ????????//?clazz的父類為:?java.lang.Object ????????//?獲取所有的接口 ????????Class<?>?intes[]?=?clazz.getInterfaces(); ????????System.out.println("clazz實(shí)現(xiàn)的接口有:"); ????????for?(int?i?=?0;?i?<?intes.length;?i++)?{ ????????????System.out.println((i?+?1)?+?":"?+?intes[i].getName()); ????????} ????????//?clazz實(shí)現(xiàn)的接口有: ????????//?1:java.io.Serializable ????} } |
獲取某個類中的全部構(gòu)造函數(shù) - 詳見下例
通過反射機(jī)制實(shí)例化一個類的對象
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | package?net.xsoftlab.baike; import?java.lang.reflect.Constructor; public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????Class<?>?class1?=?null; ????????class1?=?Class.forName("net.xsoftlab.baike.User"); ????????//?第一種方法,實(shí)例化默認(rèn)構(gòu)造方法,調(diào)用set賦值 ????????User?user?=?(User)?class1.newInstance(); ????????user.setAge(20); ????????user.setName("Rollen"); ????????System.out.println(user); ????????//?結(jié)果?User?[age=20,?name=Rollen] ????????//?第二種方法?取得全部的構(gòu)造函數(shù)?使用構(gòu)造函數(shù)賦值 ????????Constructor<?>?cons[]?=?class1.getConstructors(); ????????//?查看每個構(gòu)造方法需要的參數(shù) ????????for?(int?i?=?0;?i?<?cons.length;?i++)?{ ????????????Class<?>?clazzs[]?=?cons[i].getParameterTypes(); ????????????System.out.print("cons["?+?i?+?"]?("); ????????????for?(int?j?=?0;?j?<?clazzs.length;?j++)?{ ????????????????if?(j?==?clazzs.length?-?1) ????????????????????System.out.print(clazzs[j].getName()); ????????????????else ????????????????????System.out.print(clazzs[j].getName()?+?","); ????????????} ????????????System.out.println(")"); ????????} ????????//?結(jié)果 ????????//?cons[0]?(java.lang.String) ????????//?cons[1]?(int,java.lang.String) ????????//?cons[2]?() ????????user?=?(User)?cons[0].newInstance("Rollen"); ????????System.out.println(user); ????????//?結(jié)果?User?[age=0,?name=Rollen] ????????user?=?(User)?cons[1].newInstance(20,?"Rollen"); ????????System.out.println(user); ????????//?結(jié)果?User?[age=20,?name=Rollen] ????} } class?User?{ ????private?int?age; ????private?String?name; ????public?User()?{ ????????super(); ????} ????public?User(String?name)?{ ????????super(); ????????this.name?=?name; ????} ????public?User(int?age,?String?name)?{ ????????super(); ????????this.age?=?age; ????????this.name?=?name; ????} ????public?int?getAge()?{ ????????return?age; ????} ????public?void?setAge(int?age)?{ ????????this.age?=?age; ????} ????public?String?getName()?{ ????????return?name; ????} ????public?void?setName(String?name)?{ ????????this.name?=?name; ????} ????@Override ????public?String?toString()?{ ????????return?"User?[age="?+?age?+?",?name="?+?name?+?"]"; ????} } |
獲取某個類的全部屬性
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package?net.xsoftlab.baike; import?java.io.Serializable; import?java.lang.reflect.Field; import?java.lang.reflect.Modifier; public?class?TestReflect?implements?Serializable?{ ????private?static?final?long?serialVersionUID?=?-2862585049955236662L; ????public?static?void?main(String[]?args)?throws?Exception?{ ????????Class<?>?clazz?=?Class.forName("net.xsoftlab.baike.TestReflect"); ????????System.out.println("===============本類屬性==============="); ????????//?取得本類的全部屬性 ????????Field[]?field?=?clazz.getDeclaredFields(); ????????for?(int?i?=?0;?i?<?field.length;?i++)?{ ????????????//?權(quán)限修飾符 ????????????int?mo?=?field[i].getModifiers(); ????????????String?priv?=?Modifier.toString(mo); ????????????//?屬性類型 ????????????Class<?>?type?=?field[i].getType(); ????????????System.out.println(priv?+?"?"?+?type.getName()?+?"?"?+?field[i].getName()?+?";"); ????????} ????????? ????????System.out.println("==========實(shí)現(xiàn)的接口或者父類的屬性=========="); ????????//?取得實(shí)現(xiàn)的接口或者父類的屬性 ????????Field[]?filed1?=?clazz.getFields(); ????????for?(int?j?=?0;?j?<?filed1.length;?j++)?{ ????????????//?權(quán)限修飾符 ????????????int?mo?=?filed1[j].getModifiers(); ????????????String?priv?=?Modifier.toString(mo); ????????????//?屬性類型 ????????????Class<?>?type?=?filed1[j].getType(); ????????????System.out.println(priv?+?"?"?+?type.getName()?+?"?"?+?filed1[j].getName()?+?";"); ????????} ????} } |
獲取某個類的全部方法
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | package?net.xsoftlab.baike; import?java.io.Serializable; import?java.lang.reflect.Method; import?java.lang.reflect.Modifier; public?class?TestReflect?implements?Serializable?{ ????private?static?final?long?serialVersionUID?=?-2862585049955236662L; ????public?static?void?main(String[]?args)?throws?Exception?{ ????????Class<?>?clazz?=?Class.forName("net.xsoftlab.baike.TestReflect"); ????????Method?method[]?=?clazz.getMethods(); ????????for?(int?i?=?0;?i?<?method.length;?++i)?{ ????????????Class<?>?returnType?=?method[i].getReturnType(); ????????????Class<?>?para[]?=?method[i].getParameterTypes(); ????????????int?temp?=?method[i].getModifiers(); ????????????System.out.print(Modifier.toString(temp)?+?"?"); ????????????System.out.print(returnType.getName()?+?"??"); ????????????System.out.print(method[i].getName()?+?"?"); ????????????System.out.print("("); ????????????for?(int?j?=?0;?j?<?para.length;?++j)?{ ????????????????System.out.print(para[j].getName()?+?"?"?+?"arg"?+?j); ????????????????if?(j?<?para.length?-?1)?{ ????????????????????System.out.print(","); ????????????????} ????????????} ????????????Class<?>?exce[]?=?method[i].getExceptionTypes(); ????????????if?(exce.length?>?0)?{ ????????????????System.out.print(")?throws?"); ????????????????for?(int?k?=?0;?k?<?exce.length;?++k)?{ ????????????????????System.out.print(exce[k].getName()?+?"?"); ????????????????????if?(k?<?exce.length?-?1)?{ ????????????????????????System.out.print(","); ????????????????????} ????????????????} ????????????}?else?{ ????????????????System.out.print(")"); ????????????} ????????????System.out.println(); ????????} ????} } |
通過反射機(jī)制調(diào)用某個類的方法
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package?net.xsoftlab.baike; import?java.lang.reflect.Method; public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????Class<?>?clazz?=?Class.forName("net.xsoftlab.baike.TestReflect"); ????????//?調(diào)用TestReflect類中的reflect1方法 ????????Method?method?=?clazz.getMethod("reflect1"); ????????method.invoke(clazz.newInstance()); ????????//?Java?反射機(jī)制?-?調(diào)用某個類的方法1. ????????//?調(diào)用TestReflect的reflect2方法 ????????method?=?clazz.getMethod("reflect2",?int.class,?String.class); ????????method.invoke(clazz.newInstance(),?20,?"張三"); ????????//?Java?反射機(jī)制?-?調(diào)用某個類的方法2. ????????//?age?->?20.?name?->?張三 ????} ????public?void?reflect1()?{ ????????System.out.println("Java?反射機(jī)制?-?調(diào)用某個類的方法1."); ????} ????public?void?reflect2(int?age,?String?name)?{ ????????System.out.println("Java?反射機(jī)制?-?調(diào)用某個類的方法2."); ????????System.out.println("age?->?"?+?age?+?".?name?->?"?+?name); ????} } |
通過反射機(jī)制操作某個類的屬性
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package?net.xsoftlab.baike; import?java.lang.reflect.Field; public?class?TestReflect?{ ????private?String?proprety?=?null; ????public?static?void?main(String[]?args)?throws?Exception?{ ????????Class<?>?clazz?=?Class.forName("net.xsoftlab.baike.TestReflect"); ????????Object?obj?=?clazz.newInstance(); ????????//?可以直接對?private?的屬性賦值 ????????Field?field?=?clazz.getDeclaredField("proprety"); ????????field.setAccessible(true); ????????field.set(obj,?"Java反射機(jī)制"); ????????System.out.println(field.get(obj)); ????} } |
反射機(jī)制的動態(tài)代理
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | //?獲取類加載器的方法 TestReflect?testReflect?=?new?TestReflect(); ????????System.out.println("類加載器??"?+?testReflect.getClass().getClassLoader().getClass().getName()); package?net.xsoftlab.baike; import?java.lang.reflect.InvocationHandler; import?java.lang.reflect.Method; import?java.lang.reflect.Proxy; //定義項目接口 interface?Subject?{ ????public?String?say(String?name,?int?age); } //?定義真實(shí)項目 class?RealSubject?implements?Subject?{ ????public?String?say(String?name,?int?age)?{ ????????return?name?+?"??"?+?age; ????} } class?MyInvocationHandler?implements?InvocationHandler?{ ????private?Object?obj?=?null; ????public?Object?bind(Object?obj)?{ ????????this.obj?=?obj; ????????return?Proxy.newProxyInstance(obj.getClass().getClassLoader(),?obj.getClass().getInterfaces(),?this); ????} ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{ ????????Object?temp?=?method.invoke(this.obj,?args); ????????return?temp; ????} } /** ?*?在java中有三種類類加載器。 ?*? ?*?1)Bootstrap?ClassLoader?此加載器采用c++編寫,一般開發(fā)中很少見。 ?*? ?*?2)Extension?ClassLoader?用來進(jìn)行擴(kuò)展類的加載,一般對應(yīng)的是jrelibext目錄中的類 ?*? ?*?3)AppClassLoader?加載classpath指定的類,是最常用的加載器。同時也是java中默認(rèn)的加載器。 ?*? ?*?如果想要完成動態(tài)代理,首先需要定義一個InvocationHandler接口的子類,已完成代理的具體操作。 ?*? ?*?@author?xsoftlab.net ?*? ?*/ public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????MyInvocationHandler?demo?=?new?MyInvocationHandler(); ????????Subject?sub?=?(Subject)?demo.bind(new?RealSubject()); ????????String?info?=?sub.say("Rollen",?20); ????????System.out.println(info); ????} } |
4反射機(jī)制的應(yīng)用實(shí)例
在泛型為Integer的ArrayList中存放一個String類型的對象。
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 | package?net.xsoftlab.baike; import?java.lang.reflect.Method; import?java.util.ArrayList; public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????ArrayList<Integer>?list?=?new?ArrayList<Integer>(); ????????Method?method?=?list.getClass().getMethod("add",?Object.class); ????????method.invoke(list,?"Java反射機(jī)制實(shí)例。"); ????????System.out.println(list.get(0)); ????} } |
通過反射取得并修改數(shù)組的信息
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 | package?net.xsoftlab.baike; import?java.lang.reflect.Array; public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????int[]?temp?=?{?1,?2,?3,?4,?5?}; ????????Class<?>?demo?=?temp.getClass().getComponentType(); ????????System.out.println("數(shù)組類型:?"?+?demo.getName()); ????????System.out.println("數(shù)組長度??"?+?Array.getLength(temp)); ????????System.out.println("數(shù)組的第一個元素:?"?+?Array.get(temp,?0)); ????????Array.set(temp,?0,?100); ????????System.out.println("修改之后數(shù)組第一個元素為:?"?+?Array.get(temp,?0)); ????} } |
通過反射機(jī)制修改數(shù)組的大小
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package?net.xsoftlab.baike; import?java.lang.reflect.Array; public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????int[]?temp?=?{?1,?2,?3,?4,?5,?6,?7,?8,?9?}; ????????int[]?newTemp?=?(int[])?arrayInc(temp,?15); ????????print(newTemp); ????????String[]?atr?=?{?"a",?"b",?"c"?}; ????????String[]?str1?=?(String[])?arrayInc(atr,?8); ????????print(str1); ????} ????//?修改數(shù)組大小 ????public?static?Object?arrayInc(Object?obj,?int?len)?{ ????????Class<?>?arr?=?obj.getClass().getComponentType(); ????????Object?newArr?=?Array.newInstance(arr,?len); ????????int?co?=?Array.getLength(obj); ????????System.arraycopy(obj,?0,?newArr,?0,?co); ????????return?newArr; ????} ????//?打印 ????public?static?void?print(Object?obj)?{ ????????Class<?>?c?=?obj.getClass(); ????????if?(!c.isArray())?{ ????????????return; ????????} ????????System.out.println("數(shù)組長度為:?"?+?Array.getLength(obj)); ????????for?(int?i?=?0;?i?<?Array.getLength(obj);?i++)?{ ????????????System.out.print(Array.get(obj,?i)?+?"?"); ????????} ????????System.out.println(); ????} } |
將反射機(jī)制應(yīng)用于工廠模式
Java?|?復(fù)制| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package?net.xsoftlab.baike; interface?fruit?{ ????public?abstract?void?eat(); } class?Apple?implements?fruit?{ ????public?void?eat()?{ ????????System.out.println("Apple"); ????} } class?Orange?implements?fruit?{ ????public?void?eat()?{ ????????System.out.println("Orange"); ????} } class?Factory?{ ????public?static?fruit?getInstance(String?ClassName)?{ ????????fruit?f?=?null; ????????try?{ ????????????f?=?(fruit)?Class.forName(ClassName).newInstance(); ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace(); ????????} ????????return?f; ????} } /** ?*?對于普通的工廠模式當(dāng)我們在添加一個子類的時候,就需要對應(yīng)的修改工廠類。?當(dāng)我們添加很多的子類的時候,會很麻煩。 ?*?Java?工廠模式可以參考 ?*?http://baike.xsoftlab.net/view/java-factory-pattern ?*? ?*?現(xiàn)在我們利用反射機(jī)制實(shí)現(xiàn)工廠模式,可以在不修改工廠類的情況下添加任意多個子類。 ?*? ?*?但是有一點(diǎn)仍然很麻煩,就是需要知道完整的包名和類名,這里可以使用properties配置文件來完成。 ?*? ?*?java?讀取?properties?配置文件?的方法可以參考 ?*?http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file ?*? ?*?@author?xsoftlab.net ?*/ public?class?TestReflect?{ ????public?static?void?main(String[]?args)?throws?Exception?{ ????????fruit?f?=?Factory.getInstance("net.xsoftlab.baike.Apple"); ????????if?(f?!=?null)?{ ????????????f.eat(); ????????} ????} } ? |
?
參考文章:https://www.cnblogs.com/lzq198754/p/5780331.html
轉(zhuǎn)載于:https://www.cnblogs.com/atai/p/10308287.html
總結(jié)
以上是生活随笔為你收集整理的[转]Java反射机制详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: What are FeliCa and
- 下一篇: Oracle常见错误