天天看點

Java反射機制總結

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);
}