Java反射獲取類和物件資訊全解析
反射可以解決在編譯時無法預知物件和類是屬於那個類的,要根據程式執行時的資訊才能知道該物件和類的資訊的問題。
在兩個人協作開發時,你只要知道對方的類名就可以進行初步的開發了。
獲取類物件
- Class.forName(String clazzName)靜態方法
- 呼叫類的class屬性,Person.class返回的就是Person的class物件(推薦使用)
- 呼叫某個物件的getClass()方法
具體使用還是要根據實際來選擇,第一種方式是比較自由的,只要知道一個類名就可以了,其不會做該類是否存在的校驗,第二種、第三種則會做校驗
獲取類的資訊
獲取類構造器
Connstructor<T> getConstructor(Class<?>...parameterTypes)
:返回此Class物件對應類的帶指定形參的public構造器Constructor<?>[] getConstructors()
:返回此Class物件對應類的所有public構造器Constructor<T>[] getDeclaredConstructor(Class<?>...parameterTypes)
:返回此class物件對應類的帶指定引數的構造器,與構造器的訪問許可權無關Constructor<?>[] getDeclaredConstructors()
:返回此class物件對應類的所有構造器,與構造器的訪問許可權無關
獲取類成員方法
Method getMethod(String name,Class<?>...parameterTypes)
:返回此class物件對應類的帶指定形參的public方法Method[] getMethods()
:返回此class物件所表示的類的所有public方法Method getDeclaredMethod(string name,Class<?>...parameterTypes)
:返回此class物件對應類的帶指定形參的方法,與方法訪問許可權無關Method[] getDeclaredMethods()
:返回此class物件對應類的全部方法,與方法的訪問許可權無關
獲取類成員變數
Field getField(String name)
:返回此class物件對應類的指定名稱的public成員變數Field[] getFields()
:返回此class物件對應類的所有public成員變數Field getDeclaredField(String name)
:返回此class物件對應類的指定名稱的成員變數,與成員變數訪問許可權無關Field[] getDeclaredFields()
:返回此class物件對應類的全部成員變數,與成員變數的訪問許可權無關
獲取類註解
<A extends Annotation>A getAnnotation(Class<A>annotationClass)
:嘗試獲取該class物件對應類上村子的指定型別的Annotation,如果該型別註解不存在,則返回null<A extends Annotation>A getDeclaredAnnotation(Class<A>annotationClass)
:這是Java 8中新增的,該方法獲取直接修飾該class物件對應類的指定型別的Annotation,如果不存在,則返回nullAnnotation[] getAnnotations()
:返回修飾該class物件對應類上存在的所有AnnotationAnnotation[] getDeclaredAnnotations()
:返回修飾該Class物件對應類上存在的所有Annotation<A extends Annotation>A[] getAnnotationByType(Class<A>annotationClass)
:該方法的功能與前面介紹的getAnnotation()方法基本相似,但由於Java8增加了重複註解功能,因此需要使用該方法獲取修飾該類的指定型別的多個Annotation<A extends Annotation>A[] getDeclaredAnnotationByType(Class<A>annotationClass)
:該方法發功能與前面介紹的getDeclaredAnnotations()方法相似,也是因為Java8的重複註解的功能,需要使用該方法獲取直接修飾該類的指定型別的多個Annotation
獲取該類內部類
Class<?>[] getDeclaredClasses()
:返回該class隊形對應類裡包含的全部內部類
獲取該類物件所在的外部類
Class<?> getDeclaringClass()
:返回該Class物件對應類所在的外部類
獲取該類物件對應類所實現的介面
Class<?>[] getInterfaces()
:返回該Class物件對應類所實現的全部介面
獲取該類物件對應類所繼承的父類
Class<? super T> getSuperclass()
:返回該Class物件對應類的超類的Class物件
獲取該類物件對應類的修飾符、所在包、類名等基本資訊
int getModifiers()
:返回此類或介面的所有修飾符,修飾符由public、protected、private、final、static、abstract等對應的常量組成,返回的整數應使用Modifier工具類的方法來解碼,才可以獲取真是的修飾符Package getPackage()
:獲取該類的包String getName()
:以字串形式返回此CLass物件所表示的類的簡稱
判斷該類是否為介面、列舉、註解型別
boolean isAnnotation()
:返回此class物件是否表示一個註解型別boolean isAnnotationPresent(Class<? extends Annotation>annotationClass)
:判斷此Class物件是否使用類Annotation修飾boolean isAnonymousClass()
:返回此class物件是否是一個匿名類boolean isArray()
:返回此class物件是否表示一個陣列類boolean isEnum()
:返回此class物件是否表示一個列舉boolean isInterface()
:返回此class物件是否表示一個介面boolean isInstance(Object obj)
:判斷obj是否是此class物件的例項,該方法可以完全代替instanceof操作符
public interface Colorable { public void value(); }
public class ClassInfo { public static void main(String[] args) throws NoSuchMethodException, SecurityException { Class<Colorable> cls=Colorable.class; System.out.println(cls.getMethod("value")); System.out.println(cls.isAnnotation()); System.out.println(cls.isInterface()); } }
結果
public abstract void com.em.Colorable.value() false true
Java8中新增的方法引數反射
int getParameterCount()
:獲取該構造器或方法的形參個數Parameter[] getParameters()
:獲取該構造器或方法的所有形參getModifiers()
:獲取修飾該形參的修飾符String getName()
:獲取形參名Type getParameterizedType()
:獲取帶泛型的形參型別Class<?>getType()
:獲取形參型別boolean isNamePresent()
:該方法返回該類的class檔案中是否包含了方法的形參名資訊boolean isVarArgs()
:該方法用於判斷該引數是否為個數可變的形參
public class Test { public void getInfo(String str,List<String>list){ System.out.println("成功"); } }
public class ClassInfo { public static void main(String[] args) throws NoSuchMethodException, SecurityException { Class<Test> cls=Test.class; Method med=cls.getMethod("getInfo", String.class,List.class); System.out.println(med.getParameterCount()); Parameter[] params=med.getParameters(); System.out.println(params.length); for(Parameter par:params){ System.out.println(par.getName()); System.out.println(par.getType()); System.out.println(par.getParameterizedType()); } } }
結果
2 2 arg0 class java.lang.String class java.lang.String arg1 interface java.util.List java.util.List<java.lang.String>
反射生成物件
- 使用Class物件的newInstance()方法建立Class物件的例項,該方法要求要有預設構造器(比較常用)
- 先使用Class物件獲取指定的Constructor物件,在呼叫Constructor物件的newInstance()方法來建立該Class物件對應類的例項
反射呼叫方法
Object invoke(Object obj,Object...args)
:該方法中的obj是執行該方法的主調,後面的args是執行該方法時傳入該方法的實參
public class Test { public Test(String str) { System.out.println(str); } public void getInfo(String str){ System.out.println(str); } }
public class ClassInfo { public static void main(String[] args) throws Exception { Class<Test> cls=Test.class; Constructor<Test>construct=cls.getConstructor(String.class); Test test=construct.newInstance("初始化"); Method med=cls.getMethod("getInfo", String.class); med.invoke(test, "呼叫方法成功"); } }
結果
初始化 呼叫方法成功
接下來看官仔細看下面的栗子
public class Test { public Test(String str) { System.out.println(str); } //私有方法 private void getInfo(String str){ System.out.println(str); } }
public class ClassInfo { public static void main(String[] args) throws Exception { Class<Test> cls=Test.class; Constructor<Test>construct=cls.getConstructor(String.class); Test test=construct.newInstance("初始化"); //為啥使用這個方法呢? Method med=cls.getDeclaredMethod("getInfo", String.class); //為啥使用這個方法呢? med.setAccessible(true); med.invoke(test, "呼叫方法成功"); } }
結果
初始化 呼叫方法成功
setAccessible(boolean flag):將值設為true,指示該Method在使用是應該取消Java語言的訪問許可權檢查
訪問成員變數值
getXxx(Object obj)
:獲取obj物件的該成員變數的值。此處的Xxx對應8種基本型別,如果該成員變數的型別是引用型別的,則去掉Xxx部分setXxx(Object obj,Xxx val)
:將obj物件的該成員變數設定為val值。此處的Xxx對應8中基本型別,如果該成員變數的型別是引用型別,則取消set後面的Xxx
以上兩個方法可以方法所有的成員變數,包括private的私有成員變數
public class Test { private int num; public Test(String str) { System.out.println(str); } private void getInfo(String str){ System.out.println(str); } public int getNum() { return num; } public void setNum(int num) { this.num = num; } }
public class ClassInfo { public static void main(String[] args) throws Exception { Class<Test> cls=Test.class; Constructor<Test>construct=cls.getConstructor(String.class); Test test=construct.newInstance("初始化"); Method med=cls.getDeclaredMethod("getInfo", String.class); med.setAccessible(true); med.invoke(test, "呼叫方法成功"); Field fld=cls.getDeclaredField("num"); fld.setAccessible(true); fld.setInt(test, 12); System.out.println(fld.getInt(test)); } }
結果
初始化 呼叫方法成功 12
運算元組
java.lang.reflect包下有一個Array類,其可以動態建立陣列
static Object newInstance(Class<?>componentType,int...length)
:建立一個具有指定的元素型別、指定維度的新陣列
static xxx getXxx(Object array,int index)
:返回array陣列中第index個元素。其中xxx是各種基本資料型別,如果陣列元素是引用型別,則該方法變為get()
static void setXxx(Object array,int index,xxx val)
:將array陣列中低index 個元素的值設為val,其中xxx是各種基本資料型別,如果陣列元素是引用型別,則該方法變為set()
public class ArrayInfo { public static void main(String[] args) { Object arrays=Array.newInstance(String.class, 3); Array.set(arrays, 0, "第一個"); Array.set(arrays, 1, "第二個"); Array.set(arrays, 2, "第三個"); System.out.println(Array.get(arrays, 2)); } }
相關文章
- Java知識點總結(反射-獲取類的資訊)Java反射
- 通過反射獲取私有內部類物件反射物件
- 通過Java反射動態獲取資訊Java反射
- 反射獲取注入到spring中的類物件的工具類反射Spring物件
- 反射--Class物件功能--獲取Method反射物件
- JAVA之反射學習1-如何獲取Class物件Java反射物件
- PHP --反射 --獲取類的方法PHP反射
- Java解析微信獲取手機號資訊Java
- Java 通過反射獲取類的資訊(成員變數,成員方法,構造方法)Java反射變數構造方法
- java 獲取物件大小Java物件
- 揭秘Java反射:如何輕鬆獲取類的屬性及父類屬性Java反射
- 獲取物件屬性型別、屬性名稱、屬性值的研究:反射和JEXL解析引擎物件型別反射
- java反射構建物件和方法的反射呼叫Java反射物件
- 通過反射獲取類的類名,方法和內部成員變數反射變數
- 反射-獲取class檔案物件的三種方式反射物件
- java反射全解Java反射
- Java 物件和類Java物件
- Java 類和物件Java物件
- Java物件和類Java物件
- Java獲取Class物件的方式和例項化物件的方式Java物件
- 獲取APK檔案的簽名資訊,反射實現APK反射
- java獲取redis的日誌資訊和動態監控資訊JavaRedis
- 建立獲取Springbean物件工具類SpringBean物件
- Java列舉類、註解和反射Java反射
- 解析Java類和物件的初始化過程(轉)Java物件
- 對比分析Java反射獲取例項的速度Java反射
- C#通過反射獲取類中的方法和引數個數,反射呼叫方法帶引數C#反射
- Oracle獲取所有表名資訊和獲取指定表名欄位資訊Oracle
- 複習JAVA面相物件(類和物件)Java物件
- 物件獲取原型物件物件原型
- Java——通過反射獲取函式引數名稱Java反射函式
- Java反射獲取位元組碼以及判斷型別Java反射型別
- 獲取行政區劃資訊(省、市)工具類
- Java 獲取碟符及分類Java
- Java動態獲取某個介面下所有的實現類物件集合Java物件
- PHP 物件導向 (十一)反射類PHP物件反射
- 3.java類和物件Java物件
- Java 學習:物件和類Java物件