Java反射機制:反射機制是在運作狀态中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動态擷取的資訊以及動态調用對象的方法的功能。
擷取類資訊:
擷取内容 | 方法簽名 |
構造器 | Constructor getConstructor(Class… parameterTypes) |
包含的方法 | Method getMethod(String name, Class… parameterTypes) |
包含的屬性 | Field getField(String name) |
包含的 | Annotation A getAnnotation(Class annotationClass) |
内部類 | Class[] getDeclaredClasses() |
外部類 | Class getDeclaringClass() |
所實作的接口 | Class[] getInterfaces() |
修飾符 | int getModifiers() |
所在包 | Package getPackage() |
類名 | String getName() |
簡稱 | String getSimpleName() |
判斷類資訊:
判斷内容 | 方法簽名 |
注解類型? | boolean isAnnotation() |
使用了該Annotation修飾? | boolean isAnnotationPresent(Class annotationClass) |
匿名類? | boolean isAnonymousClass() |
數組? | boolean isArray() |
枚舉? | boolean isEnum() |
原始類型? | boolean isPrimitive() |
接口? | boolean isInterface() |
obj是否是該Class的執行個體 | boolean isInstance(Object obj) |
1 擷取該類對象對應類的修飾符、所在包、類名等基本資訊
int getModifiers():傳回此類或接口的所有修飾符,修飾符由public、protected、private、final、static、abstract等對應的常量組成,傳回的整數應使用Modifier工具類的方法來解碼,才可以擷取真是的修飾符
PUBLIC: 1,PRIVATE: 2,PROTECTED: 4,STATIC: 8,FINAL: 16,SYNCHRONIZED: 32,VOLATILE: 64,TRANSIENT: 128,NATIVE: 256,INTERFACE: 512,ABSTRACT: 1024,STRICT: 2048
Package getPackage():擷取該類的包
String getName():以字元串形式傳回此CLass對象所表示的類的簡稱
示例代碼:
/*
* 擷取類名
*/
public static String getClassAllName(Person person){
return person.getClass().getName();
}
/*
* 擷取包名
*/
public static String getPackageName(Person person){
//System.out.println(person.getClass().getPackage().getName());
return person.getClass().getPackage().getName() ;
}
/*
* 擷取修飾符
*/
public static String getModifiersName(Person person){
String str=null;
int modifier = person.getClass().getModifiers();
return
2 類成員方法的反射
Method getMethod(String name,Class<?>...parameterTypes):傳回此class對象對應類的帶指定形參的public方法
Method[] getMethods():傳回此class對象所表示的類的所有public方法
Method getDeclaredMethod(string name,Class<?>...parameterTypes):傳回此class對象對應類的帶指定形參的方法,與方法通路權限無關
Method[] getDeclaredMethods():傳回此class對象對應類的全部方法,與方法的通路權限無關
示例代碼:
/*
* 擷取類的成員方法
* 一個成員方法就是一個method對象
* getMethod()所有的 public方法,包括父類繼承的 public
* getDeclaredMethods()擷取該類所有的方法,包括private ,但不包括繼承的方法。
*/
public static ArrayList<String> getMethodInfo(Person person){
Class<? extends Person> p=person.getClass();
//System.out.println("類的名稱:"+p.getName());
Method[] methods=p.getMethods();//擷取所有的 public方法,包括父類繼承的 public
//Method[] methods=p.getDeclaredMethods();//擷取該類所有的方法,包括private ,但不包括繼承的方法。
ArrayList<String> methodList = new ArrayList<String>();
for(int i=0;i<methods.length;i++){
String str = "";
Class returnType = methods[i].getReturnType();
str+= returnType+" ";
//得到方法名:
str+=methods[i].getName()+"(";
Class[] parameterTypes=methods[i].getParameterTypes();
for(Class c:parameterTypes){
str+=c.getName()+",";
}
if(str.endsWith(",")){
str=str.substring(0,str.length()-1);
}
str+=")";
methodList.add(str);
}
return
3 成員變量的反射
Field getField(String name):傳回此class對象對應類的指定名稱的public成員變量
Field[] getFields():傳回此class對象對應類的所有public成員變量
Field getDeclaredField(String name):傳回此class對象對應類的指定名稱的成員變量,與成員變量通路權限無關
Field[] getDeclaredFields():傳回此class對象對應類的全部成員變量,與成員變量的通路權限無關
示例代碼:
/**
* 擷取類的成員變量
* getFileds()擷取public
* getDeclaredFields()擷取所有
* @return
public static ArrayList<String> getFiledInfo(Person person){
ArrayList<String> filedList = new ArrayList<String>();
Class c=person.getClass();
//Field[] fileds=c.getFields(); //getFileds()擷取public
Field[] fileds=c.getDeclaredFields(); //getDeclaredFields()擷取所有
for(Field field:fileds){
//擷取成員變量的類型
Class filedType=field.getType();
String str = filedType.getName()+" "+field.getName();
filedList.add(str);
}
return
4 構造函數的反射
Connstructor<T> getConstructor(Class<?>...parameterTypes):傳回此Class對象對應類的帶指定形參的public構造器
Constructor<?>[] getConstructors():傳回此Class對象對應類的所有public構造器
Constructor<T>[] getDeclaredConstructor(Class<?>...parameterTypes):傳回此class對象對應類的帶指定參數的構造器,與構造器的通路權限無關
Constructor<?>[] getDeclaredConstructors():傳回此class對象對應類的所有構造器,與構造器的通路權限無關
示例代碼:
/*
* 擷取類的構造方法
*/
public static ArrayList<String> getConstructorInfo(Person person){
ArrayList<String> constructorList = new ArrayList<String>();
Class c=person.getClass();
//Constructor[] constructors = c.getConstructors();
Constructor[] constructors = c.getDeclaredConstructors();
for(Constructor cons:constructors){
String str = cons.getName()+"(";
Class[] parameterType = cons.getParameterTypes();
for(Class para:parameterType){
str += para.getName()+",";
}
if(str.endsWith(",")){
str=str.substring(0,str.length()-1);
}
str+=")";
constructorList.add(str);
}
return
5 擷取類的注解
<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
示例代碼:
/*
* 擷取類的注解
*/
public static ArrayList<String> getAnnotationInfo(Person person){
ArrayList<String> annotationList = new ArrayList<String>();
Method[] methods = person.getClass().getMethods();
for(Method m:methods){
for (Annotation annotation:m.getAnnotations()) {
System.out.println(annotation + " in method:"+ m);
String str= annotation + " in method:"+ m;
annotationList.add(str);
}
}
return
6 擷取類的内部類
Class<?>[] getDeclaredClasses():傳回該class隊形對應類裡包含的全部内部類
示例代碼:
/**
* 擷取類的内部類
*/
public static ArrayList<String> getDeclaredClassInfo(Person person){
ArrayList<String> declaredList = new ArrayList<String>();
Class c=person.getClass();
Class[] declaredClass= c.getDeclaredClasses();
for(Class cl:declaredClass){
String declaredType=cl.getTypeName();
declaredList.add(declaredType);
}
return
7 擷取類對象所在的外部類
Class<?> getDeclaringClass():傳回該Class對象對應類所在的外部類
示例代碼:
/**
* 擷取類的外部類
*/
public static String getDeclaringClassInfo(Person person){
Class c=person.getClass();
Class declaringClass= c.getDeclaringClass();
if(declaringClass!=null){
return declaringClass.getName();
}
return null;
}
8 擷取類對象對應類所實作的接口
Class<?>[] getInterfaces():傳回該Class對象對應類所實作的全部接口
示例代碼:
/**
* 擷取類的實作接口
*/
public static ArrayList<String> getInterfacesInfo(Person person){
ArrayList<String> interfaceList = new ArrayList<String>();
Class c=person.getClass();
Class[] interClass= c.getInterfaces();
//Type[] genInterType = c.getGenericInterfaces();
//AnnotatedType[] annoInterType = c.getAnnotatedInterfaces();
for(Class cl:interClass){
String interType=cl.getTypeName();
interfaceList.add(interType);
}
return
9 擷取該類對象對應類所繼承的父類
Class<? super T> getSuperclass():傳回該Class對象對應類的超類的Class對象
示例代碼:
/*
* 擷取類的繼承類
*/
public static String getSuperclassInfo(Person person){
Class c = person.getClass();
Class superClass = c.getSuperclass();
return
10 判斷該類是否為接口、枚舉、注解類型
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操作符
11 方法反射的操作
public class Person{
private static int testID;
private static String testName;
private boolean testSex;
//省略getter和setter方法
public int sumOfAge(int num1,int num2){
return
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Person();
Class cl = person.getClass();
Method method = null;
try {
method = cl.getMethod("sumOfAge", new Class[]{int.class,int.class});
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
int sum = 0;
try {
sum =(int) method.invoke(person, 12,17);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(sum);
}