反射能夠解決在編譯時沒法預知對象和類是屬於那個類的,要根據程序運行時的信息才能知道該對象和類的信息的問題。html
在兩我的協做開發時,你只要知道對方的類名就能夠進行初步的開發了。java
獲取類對象數組
Class.forName(String clazzName)靜態方法ide
調用類的class屬性,Person.class返回的就是Person的class對象(推薦使用)工具
調用某個對象的getClass()方法this
具體使用仍是要根據實際來選擇,第一種方式是比較自由的,只要知道一個類名就能夠了,其不會作該類是否存在的校驗,第二種、第三種則會作校驗component
獲取類的信息htm
獲取類構造器
Connstructor getConstructor(Class...parameterTypes):返回此Class對象對應類的帶指定形參的public構造器對象
Constructor[] getConstructors():返回此Class對象對應類的全部public構造器繼承
Constructor[] 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 getAnnotation(ClassannotationClass):嘗試獲取該class對象對應類上村子的指定類型的Annotation,若是該類型註解不存在,則返回null
A getDeclaredAnnotation(ClassannotationClass):這是Java 8中新增的,該方法獲取直接修飾該class對象對應類的指定類型的Annotation,若是不存在,則返回null
Annotation[] getAnnotations():返回修飾該class對象對應類上存在的全部Annotation
Annotation[] getDeclaredAnnotations():返回修飾該Class對象對應類上存在的全部Annotation
A[] getAnnotationByType(ClassannotationClass):該方法的功能與前面介紹的getAnnotation()方法基本類似,但因爲Java8增長了重複註解功能,所以須要使用該方法獲取修飾該類的指定類型的多個Annotation
A[] getDeclaredAnnotationByType(ClassannotationClass):該方法發功能與前面介紹的getDeclaredAnnotations()方法類似,也是由於Java8的重複註解的功能,須要使用該方法獲取直接修飾該類的指定類型的多個Annotation
獲取該類內部類
Class[] getDeclaredClasses():返回該class隊形對應類裏包含的所有內部類
獲取該類對象所在的外部類
ClassgetDeclaringClass():返回該Class對象對應類所在的外部類
獲取該類對象對應類所實現的接口
Class[] getInterfaces():返回該Class對象對應類所實現的所有接口
獲取該類對象對應類所繼承的父類
ClassgetSuperclass():返回該Class對象對應類的超類的Class對象
獲取該類對象對應類的修飾符、所在包、類名等基本信息
int getModifiers():返回此類或接口的全部修飾符,修飾符由public、protected、private、final、static、abstract等對應的常量組成,返回的整數應使用Modifier工具類的方法來解碼,才能夠獲取真是的修飾符
Package getPackage():獲取該類的包
String getName():以字符串形式返回此CLass對象所表示的類的簡稱
判斷該類是否爲接口、枚舉、註解類型
boolean isAnnotation():返回此class對象是否表示一個註解類型
boolean isAnnotationPresent(ClassannotationClass):判斷此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());
}
}
Java8中新增的方法參數反射
int getParameterCount():獲取該構造器或方法的形參個數
Parameter[] getParameters():獲取該構造器或方法的全部形參
getModifiers():獲取修飾該形參的修飾符
String getName():獲取形參名
Type getParameterizedType():獲取帶泛型的形參類型
ClassgetType():獲取形參類型
boolean isNamePresent():該方法返回該類的class文件中是否包含了方法的形參名信息
boolean isVarArgs():該方法用於判斷該參數是否爲個數可變的形參.
代碼2:
ublic 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());
}
}
}
反射生成對象
使用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));
}
操做數組
java.lang.reflect包下有一個Array類,其能夠動態建立數組
static Object newInstance(ClasscomponentType,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));
}
}