JAVA的反射機制==>用反射分析類的實現

TeaIsCold發表於2017-05-15

反射的概念:能夠分析具體類的能力的程式稱為反射

(JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。)

反射機制的作用:

    1、在程式執行中分析類的能力
    2、在執行中檢視物件
1、反射機制==>檢查類的結構:

預備知識:java.lang.reflect包中有三個類Field、Method、Constructor分別用來描述類的域(屬性/欄位)、方法、構造器

1、用反射分析類的能力(程式碼實現)

package 反射機制;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
/**
 * 利用反射分析類的能力
 */
public class ReflectionTest {

    public static void main(String[] args) {
        // 從命令列或引數讀取使用者輸入
        String name;
        if(args.length>0) name=args[0];
        else{
            Scanner in=new Scanner(System.in);
            System.out.println("輸入類名  (例如:java.util.Date):");
            name=in.next();
        }

        try {
            //獲取類名所對應的Class物件
            Class cl=Class.forName(name);
            Class supercl=cl.getSuperclass();
            //獲取類修飾符
            String modifiers=Modifier.toString(cl.getModifiers());
            if(modifiers.length()>0)
                System.out.print(modifiers+" ");
            System.out.print("calss "+name);
            if(supercl!=null&&supercl!=Object.class)
                System.out.print(" extends "+supercl.getName());
            System.out.print("{\n");

            printConstructors(cl);
            System.out.println();
            printMethods(cl);
            System.out.println();
            printFields(cl);
            System.out.println("}");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } 

    }

    /**
     * 輸出所有的構造方法
     */
    public static void printConstructors(Class cl){
        //獲取所有的構造方法物件
        Constructor[] constructors=cl.getDeclaredConstructors();
        for(Constructor c:constructors){
            String name=c.getName();
            System.out.print("  ");
            //返回一個整數,用不同的位描述public和static這樣的修飾符使用狀況
            int mod=c.getModifiers();
            //將修飾符列印出來
            String modifiers=Modifier.toString(mod);
            if(modifiers.length()>0)
                System.out.print(modifiers+' ');
            System.out.print(name+'(');

            //輸出引數型別
            Class[] paramTypes=c.getParameterTypes();
            for(int j=0;j<paramTypes.length;j++){
                if(j>0)
                    System.out.print(", ");
                System.out.print(paramTypes[j].getName());
            }
            System.out.println(");");
        }
    }
    /**
     * 輸出類的所有方法
     * @param cl
     */
    public static void printMethods(Class cl){
        Method[] methods=cl.getDeclaredMethods();
        for(Method m:methods){
            Class retType=m.getReturnType();
            String name=m.getName();

            System.out.print("  ");
            //輸出宣告、返回型別、方法名
            String modifiers=Modifier.toString(m.getModifiers());
            if(modifiers.length()>0)
                System.out.print(modifiers+' ');
            System.out.print(retType.getName()+" "+name+"(");
            //輸出引數型別
            Class[] paramTypes=m.getParameterTypes();
            for(int j=0;j<paramTypes.length;j++){
                if(j>0)
                    System.out.print(", ");
                System.out.print(paramTypes[j].getName());
            }
            System.out.println(");");
        }
    }
    /**
     * 輸出類的所有域(屬性)
     * @param cl
     */
    public static void printFields(Class cl){
        Field[] fields=cl.getDeclaredFields();
        for(Field f:fields){
            //返回域所屬型別的物件
            Class type=f.getType();
            String name=f.getName();
            System.out.print("  ");
            String modifiers=Modifier.toString(f.getModifiers());
            if(modifiers.length()>0)
                System.out.print(modifiers+' ');
            System.out.println(type.getName()+" "+name+";");
        }
    }
}

輸出結果:

輸入類名  (例如:java.util.Date):
java.util.Date
public calss java.util.Date{
    public java.util.Date(int, int, int, int, int, int);
    public java.util.Date(java.lang.String);
    public java.util.Date();
    public java.util.Date(long);
    public java.util.Date(int, int, int);
    public java.util.Date(int, int, int, int, int);

    public boolean after(java.util.Date);
    public boolean before(java.util.Date);
    public boolean equals(java.lang.Object);
    public java.lang.String toString();
    public int hashCode();
    public java.lang.Object clone();
    public int compareTo(java.util.Date);
    public volatile int compareTo(java.lang.Object);
    private void readObject(java.io.ObjectInputStream);
    private void writeObject(java.io.ObjectOutputStream);
    private final sun.util.calendar.BaseCalendar$Date normalize(sun.util.calendar.BaseCalendar$Date);
    private final sun.util.calendar.BaseCalendar$Date normalize();
    public static long parse(java.lang.String);
    public int getDate();
    public static java.util.Date from(java.time.Instant);
    public long getTime();
    private static final java.lang.StringBuilder convertToAbbr(java.lang.StringBuilder, java.lang.String);
    private final sun.util.calendar.BaseCalendar$Date getCalendarDate();
    private static final sun.util.calendar.BaseCalendar getCalendarSystem(int);
    private static final sun.util.calendar.BaseCalendar getCalendarSystem(sun.util.calendar.BaseCalendar$Date);
    private static final sun.util.calendar.BaseCalendar getCalendarSystem(long);
    public int getDay();
    public int getHours();
    private static final synchronized sun.util.calendar.BaseCalendar getJulianCalendar();
    static final long getMillisOf(java.util.Date);
    public int getMinutes();
    public int getMonth();
    public int getSeconds();
    private final long getTimeImpl();
    public int getTimezoneOffset();
    public int getYear();
    public void setDate(int);
    public void setHours(int);
    public void setMinutes(int);
    public void setMonth(int);
    public void setSeconds(int);
    public void setYear(int);
    public java.lang.String toGMTString();
    public java.time.Instant toInstant();
    public java.lang.String toLocaleString();
    public void setTime(long);
    public static long UTC(int, int, int, int, int, int);

    private static final sun.util.calendar.BaseCalendar gcal;
    private static sun.util.calendar.BaseCalendar jcal;
    private transient long fastTime;
    private transient sun.util.calendar.BaseCalendar$Date cdate;
    private static int defaultCenturyStart;
    private static final long serialVersionUID;
    private static final [Ljava.lang.String; wtb;
    private static final [I ttb;
}

上述程式碼在執行過程中分別分析了一個類的構造器、方法、域

相關文章