Reflection:Java反射機制基礎

反射機制是什麼

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

反射機制能作什麼

反射機制主要提供瞭如下功能:數組

  • 在運行時判斷任意一個對象所屬的類函數

  • 在運行時構造任意一個類的對象代理

  • 在運行時判斷任意一個類所具備的成員變量和方法code

  • 在運行時調用任意一個對象的方法對象

  • 生成動態代理繼承

反射機制的相關API

經過一個對象得到完整的包名和類名

@Test
    public void getReflectionName() {
        String str = new String();
        System.out.println(str.getClass().getName()); // java.lang.String
        System.out.println(str.getClass().getSimpleName()); // String
    }

實例化Class類對象(三種方式)

@Test
    public void getInitClazz() {

        try {
            // 方式一:
            Class<?> clazz_1 = Class.forName("java.lang.String");
            // 方式二:
            Class<?> clazz_2 = new String().getClass();
            // 方式三:
            Class<?> clazz_3 = String.class;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

獲取一個對象的父類與實現的接口

@Test
    public void getParentAndIntefaces() {

        try {
            Class<?> clazz = Class.forName("java.lang.String");
            // 取得父類
            Class<?> parentClass = clazz.getSuperclass();
            System.out.println("clazz的父類爲:" + parentClass.getName());// clazz的父類爲: java.lang.Object
            
            // 獲取全部的接口
            Class<?> intes[] = clazz.getInterfaces();
            System.out.println("clazz實現的接口有:");
            for (int i = 0; i < intes.length; i++) {
                System.out.println((i + 1) + ":" + intes[i].getName());
            }

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

經過反射獲取屬性

@Test
    public void getFieldsByReflect() {

        try {
                Class<?> clazz = String.class ;
                // 取得本類的所有屬性
                Field[] declaredFields = clazz.getDeclaredFields(); 
                // 取得實現的接口或者父類的屬性
                Field[] fields = clazz.getFields();
                
                //遍歷本類屬性
                for (Field field : declaredFields) {
                    // 權限修飾符
                    int mo = field.getModifiers();
                    String priv = Modifier.toString(mo);
                    // 屬性類型
                    Class<?> type = field.getType();
                    System.out.println(priv + " " + type.getName() + " " + field.getName() + ";");
                }
                
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

經過反射獲取方法函數

@Test
    public void getMethodsByReflect() {

        try {
            Class<?> clazz = String.class ;
            // 類的全部公用(public)方法包括其繼承類的公用方法,固然也包括它所實現接口的方法
            Method[] methods = clazz.getMethods();
            // 類或接口聲明的全部方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法。固然也包括它所實現接口的方法
            Method[] declaredMethods = clazz.getDeclaredMethods();
            
            //遍歷本類屬性
            for (Method method : methods) {
                // 權限修飾符
                int mo = method.getModifiers();
                String priv = Modifier.toString(mo);
                //返回值
                Class<?> returnType = method.getReturnType();
                //方法名
                String methodName = method.getName();
                //方法參數類型
                Class<?>[] parameterTypes = method.getParameterTypes();
                //拋出的異常
                Class<?>[] exceptionTypes = method.getExceptionTypes();
            }
            
    } catch (Exception e) {
        e.printStackTrace();
    }
    }

經過反射獲取構造方法

@Test
    public void getConstructorsByReflect() {

        try {
            Class<?> clazz = Class.forName("java.lang.String");
            
            //獲取構造方法
            Constructor<?>[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                
                //獲取構造方法的參數
                Class[] parameterTypes = constructor.getParameterTypes();
                for (Class clazzType : parameterTypes) {
                    System.out.print(clazzType.getSimpleName() + "   ");
                }
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

經過反射機制設置屬性

@Test
    public void oprFieldsByReflect() {

        try {
            
            Class<?> clazz = Class.forName("java.lang.String");
            //實例化對象
            String str = new String("String");
            //能夠直接對 private 的屬性賦值
            Field field = clazz.getDeclaredField("hash");
            //改變屬性
            field.setAccessible(true);
            //調用映射屬性
            field.set(str, 0);
            
            System.out.println(field.get(str));
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

經過反射機制調用方法

@Test
    public void oprMethodsByReflect() {

        try {
            Class<?> clazz = Class.forName("java.lang.String");
            //實例化一個對象
            String str = new String("String");
            //反射出一個方法
            Method method =  clazz.getMethod("startsWith", String.class);
            //調用映射方法
            Object result = method.invoke(str, "Str");
            
            System.out.println(result);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

實例應用

在泛型爲Integer的ArrayList中存放一個String類型的對象

/**
     * 在泛型爲Integer的ArrayList中存放一個String類型的對象
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
           ArrayList<Integer> list = new ArrayList<Integer>();
            Method method = list.getClass().getMethod("add", Object.class);
            method.invoke(list, "Java反射機制實例");
            System.out.println(list.get(0));
    }

經過反射取得並修改數組的信息

/**
     * 經過反射取得並修改數組的信息
     * 
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
        int[] temp = { 1, 2, 3, 4, 5 };
        Class<?> demo = temp.getClass().getComponentType();
        
        System.out.println("數組類型: " + demo.getName());
        
        System.out.println("數組長度  " + Array.getLength(temp));
        
        System.out.println("數組的第一個元素: " + Array.get(temp, 0));
        
        Array.set(temp, 0, 100);
        System.out.println("修改以後數組第一個元素爲: " + Array.get(temp, 0));
    }

經過反射機制修改數組的大小

/**
     * 經過反射機制修改數組的大小
     * 
     * @throws Exception
     */
    @Test
    public void test() throws Exception {

        int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int[] newTemp = (int[]) arrayInc(temp, 15);
        print(newTemp);
        String[] atr = { "a", "b", "c" };
        String[] str1 = (String[]) arrayInc(atr, 8);
        print(str1);
    }

    // 修改數組大小
    private static Object arrayInc(Object obj, int len) {
        Class<?> arr = obj.getClass().getComponentType();
        Object newArr = Array.newInstance(arr, len);
        int co = Array.getLength(obj);
        System.arraycopy(obj, 0, newArr, 0, co);
        return newArr;
    }

    // 打印
    private static void print(Object obj) {
        Class<?> c = obj.getClass();
        if (!c.isArray()) {
            return;
        }
        System.out.println("數組長度爲: " + Array.getLength(obj));
        for (int i = 0; i < Array.getLength(obj); i++) {
            System.out.print(Array.get(obj, i) + " ");
        }
        System.out.println();
    }
相關文章
相關標籤/搜索