1. 程式人生 > >【Java】java使用反射訪問物件方法和成員變數

【Java】java使用反射訪問物件方法和成員變數

雖然java是一門靜態語言,但是java的反射機制卻給java提供了很強大的動態特性,其特點是能讓java支援在執行時才能得知名稱與內部結構的類,並能訪問其所有的方法和成員變數,包括私有方法和私有成員變數。下面我寫了一個比較簡潔的測試程式碼,供參考和使用。

測試類

//OBClass.java
package com.obo.javaassistdemo;

public class OBClass {
    public int publicField= 999;
    private int privateField = 234;

    public static void main(String[] args) {
        System.out.println("hello world" + new OBClass().privateField);
        new OBClass().privateMethod();
    }

    public void publicMethod() {
        System.out.println("test public method");
    }

    public void publicMethodWithParam(String param) {
        System.out.println("test publicMethodWithParam's param is " + param);
    }

    private void privateMethod() {
        System.out.println("test private method");
    }

    public static void staticMethod() {
        System.out.println("test static method");
    }
}

利用反射來呼叫測試類的方法和成員變數。
//JavaAssistDemo.java
package com.obo.javaassistdemo;


import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javassist.CannotCompileException;
import javassist.NotFoundException;

/**
 * Created by obo on 16/2/5.
 */
public class JavaAssistDemo {
    public static void main(String []args) throws NotFoundException, CannotCompileException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        reflex();
    }

    //反射
    private static void reflex() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
        //建立一個OBClass例項物件
        OBClass obClass = new OBClass();

        //獲取OBClass的類物件
        Class myClass = OBClass.class;

        /// 無引數的public方法
        //反射回去OBClass中的方法名為publicMethod的方法
        Method publicMethod = myClass.getDeclaredMethod("publicMethod");
        //更改publicMethode方法的可訪問屬性為public
        //訪問publicMethod方法
        publicMethod.invoke(obClass);

        /// 帶引數的public方法
        //反射回去OBClass中的方法名為publicMethod的方法
        Method publicMethodWithParam = myClass.getDeclaredMethod("publicMethodWithParam",String.class);
        //更改publicMethode方法的可訪問屬性為public
        //訪問publicMethod方法
        publicMethodWithParam.invoke(obClass,"hello");

        /// 無引數的private方法
        //反射回去OBClass中的方法名為publicMethod的方法
        Method privateMethod = myClass.getDeclaredMethod("privateMethod");
        //更改privateMethod方法的可訪問屬性為public,要想訪問private方法必須要修改這一項
        privateMethod.setAccessible(true);
        //訪問privateMethod方法
        privateMethod.invoke(obClass);

        /// 無引數的static方法
        //反射回去OBClass中的方法名為publicMethod的方法
        Method staticMethod = myClass.getDeclaredMethod("staticMethod");
        //訪問static方法,靜態方法的時候可以使用類物件作為引數
        staticMethod.invoke(myClass);

        /// 獲取public 成員變數
        Field publicField = myClass.getDeclaredField("publicField");
        publicField.setAccessible(true);
        System.out.println("" + publicField.getInt(obClass));

        /// 獲取private 成員變數
        Field privateField = myClass.getDeclaredField("privateField");
        privateField.setAccessible(true);
        System.out.println("" + privateField.getInt(obClass));

    }
}

上面分別提供了多種方法和成員變數的訪問方式,可以組合起來進行使用。

有了java的反射機制,我們可以實現非常有意思也非常靈活的功能,比如說可以使用java類來建立資料庫表的對映、也可以與javaassist的聯合起來用於修改第三方api等。