來源:segmentfault
反射可以解決在編譯時無法預知對象和類是屬於那個類的,要根據程序運行時的信息才能知道該對象和類的信息的問題。
在兩個人協作開發時,你只要知道對方的類名就可以進行初步的開發了。
獲取類對象具體使用還是要根據實際來選擇,第一種方式是比較自由的,只要知道一個類名就可以了,其不會做該類是否存在的校驗,第二種、第三種則會做校驗
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,如果不存在,則返回null
Annotation[] getAnnotations():返回修飾該class對象對應類上存在的所有Annotation
Annotation[] 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
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()falsetrue
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()); } }}
結果
22arg0class java.lang.Stringclass java.lang.Stringarg1interface java.util.Listjava.util.List<java.lang.String>
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)); }}
尚學堂:每天推送IT新技術文章,跟著我們擴展技術視野吧
即刻起關注尚學堂,發送「要課程」,
IT課程免費送!