程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java反射機制淺析

Java反射機制淺析

編輯:JAVA編程入門知識

JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。

“程序運行時,允許改變程序結構或變量類型,這種語言稱為動態語言”。從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言。但是JAVA有著一個非常突出的動態相關機制:Reflection,用在Java身上指的是我們可以於運行時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。

Java反射機制主要相關的類:
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;

Java中獲取Class有三種方式(以UserBean類為例):
1、類名.class
UserBean.class
2、對象.getClass();
UserBean userBean = new UserBean();
userBean.getClass();
3、Class.forName()
Class.forName("com.alfred.bean.UserBean");
如果是在同級目錄下可以不加路徑

需要解釋一點就是,java中一切都是對象,我們獲取的Class也是一個對象。基本類型int、float等也會在jvm的內存池像其他類型一樣生成一個Class對象。而數組等組合型數據類型也是會生成一個Class對象的,而且更令人驚訝的是,java中數組的本來面目其實就是某個類。
例如:
Class c1 = int.class;
Class c2 = Double[].class;

通過使用java反射機制可以實現:
1、運行時獲取類結構(包括類名,修飾符,屬性,方法,構造函數,父類,接口等等)
2、運行時調用類公共方法(可以傳遞方法參數)
3、運行時創建類對象

以下是一個java反射機制的實例:

package com.alfred.main;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Reflection {

    /**
     * 打印整個類的結構(包括父子類接口)
     * @param c Class對象
     */
    public static void printClassStructure(Class c) {
        try {
            // 獲取所有的屬性(不包括父類的)
            Field[] fs = c.getDeclaredFields();

            // 定義可變長的字符串,用來存儲屬性
            StringBuffer sb = new StringBuffer();
            // 通過追加的方法,將每個屬性拼接到此字符串中
            // 最外邊的public定義
            sb.append(Modifier.toString(c.getModifiers()) + " class "
                    + c.getSimpleName());
            Class superclass = c.getSuperclass();
            if (superclass != null && !superclass.getSimpleName().equals("Object")) {
                // 不是直接繼承於Object,說明有其他繼承類
                printClassStructure(superclass);
                sb.append(" extends " + superclass.getSimpleName());
            }
            Class[] interfaces = c.getInterfaces();
            if (interfaces.length > 0) {
                sb.append(" implements ");
                for (int i = 0; i < interfaces.length; i++) {
                    printClassStructure(interfaces[i]);
                    sb.append(((i != 0) ? "," : "")
                            + interfaces[i].getSimpleName());
                }
            }
            sb.append("{\n");

            // 類中的屬性
            for (Field field : fs) {
                sb.append("\t");// 縮進
                sb.append(Modifier.toString(field.getModifiers()) + " ");// 獲得屬性的修飾符,例如public,static等等
                sb.append(field.getType().getSimpleName() + " ");
                sb.append(field.getName() + ";\n");
            }

            // 類中的構造方法
            Constructor[] declaredConstructors = c.getDeclaredConstructors();
            for (Constructor constructor : declaredConstructors) {
                sb.append("\t");
                sb.append(Modifier.toString(constructor.getModifiers()) + " ");
                sb.append(c.getSimpleName() + "(");
                Class[] parameterTypes = constructor.getParameterTypes();
                for (int i = 0; i < parameterTypes.length; i++) {
                    sb.append(((i != 0) ? "," : "")
                            + parameterTypes[i].getSimpleName() + " arg" + i);
                }
                sb.append("){}\n");
            }

            // 類中的方法
            Method[] ms = c.getDeclaredMethods();
            for (Method method : ms) {
                sb.append("\t");
                sb.append(Modifier.toString(method.getModifiers()) + " ");
                sb.append(method.getReturnType().getSimpleName() + " ");
                sb.append(method.getName() + "(");
                Class<?>[] parameterTypes = method.getParameterTypes();
                for (int i = 0; i < parameterTypes.length; i++) {
                    sb.append(((i != 0) ? "," : "")
                            + parameterTypes[i].getSimpleName() + " arg" + i);
                }
                sb.append("){}\n");
            }

            sb.append("}");

            System.out.println(sb);
            System.out.println("=================================");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 得到某個對象的公共屬性
     * @param owner
     * @param fieldName
     * @return 該屬性對象
     * @throws Exception
     */
    public static Object getProperty(Object owner, String fieldName)
            throws Exception {
        Class ownerClass = owner.getClass();
        Field field = ownerClass.getDeclaredField(fieldName);
        Object property = field.get(owner);
        return property;
    }

    /**
     * 得到某類的靜態公共屬性
     * @param className 類名
     * @param fieldName 屬性名
     * @return 該屬性對象
     * @throws Exception
     */
    public static Object getStaticProperty(String className, String fieldName)
            throws Exception {
        Class ownerClass = Class.forName(className);
        Field field = ownerClass.getField(fieldName);
        Object property = field.get(ownerClass);
        return property;
    }

    /**
     * 執行某對象方法
     * @param owner 對象
     * @param methodName 方法名
     * @param args 參數
     * @return 方法返回值
     * @throws Exception
     */
    public static Object invokeMethod(Object owner, String methodName, Object[] args)
            throws Exception {
        Class ownerClass = owner.getClass();
        Class[] argsClass = new Class[args.length];
        for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }
        Method method = ownerClass.getMethod(methodName, argsClass);
        return method.invoke(owner, args);
    }

    /**
     * 執行某類的靜態方法
     * @param className 類名
     * @param methodName 方法名
     * @param args 參數數組
     * @return 執行方法返回的結果
     * @throws Exception
     */
    public static Object invokeStaticMethod(String className, String methodName,
            Object[] args) throws Exception {
        Class ownerClass = Class.forName(className);
        Class[] argsClass = new Class[args.length];
        for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }
        Method method = ownerClass.getMethod(methodName, argsClass);
        return method.invoke(null, args);
    }

    /**
     * 新建實例
     * @param className 類名
     * @param args 構造函數的參數
     * @return 新建的實例
     * @throws Exception
     */
    public static Object newInstance(String className, Object[] args) throws Exception {
        Class newClass = Class.forName(className);
        Class[] argsClass = new Class[args.length];
        for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }
        Constructor cons = newClass.getConstructor(argsClass);
        return cons.newInstance(args);
    }

    /**
     * 是不是某個類的實例
     * @param obj 實例
     * @param cls 類
     * @return 如果 obj 是此類的實例,則返回 true
     */
    public static boolean isInstance(Object obj, Class cls) {
        return cls.isInstance(obj);
    }

    /**
     * 得到數組中的某個元素
     * @param array 數組
     * @param index 索引
     * @return 返回指定數組對象中索引組件的值
     */
    public static Object getByArray(Object array, int index) {
        return Array.get(array, index);
    }

}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved