1. 程式人生 > >Java反射之——方法的反射操作

Java反射之——方法的反射操作

Java反射中 ,方法的反射操作是通過Method物件呼叫invoke(物件,引數)方法,之前我們需要知道怎樣來確定一個方法?

注:通過方法名和引數列表我們可以唯一確定一個方法。

首先我們獲取方法就是獲取類中的資訊,獲取類的資訊需要得到類型別,因此我們通過已知A的例項物件a1,呼叫getClass()方法得到A類型別,然後呼叫getMethod方法獲取到Method物件,然後Method物件呼叫invoke()方法。

整個流程:

一、已知A類,通過例項物件a1獲取類型別

class A{
    public void print() {
        System.out.println("hello world");
    }
    public void print(int a, int b) {
        System.out.println(a+b);
    }
    public void print(String a, String b) {
        System.out.println(a.toUpperCase()+","+b.toLowerCase());
    }
}

TestA a1 = new TestA();

//通過物件獲取類的類型別,可以獲取到類的資訊
Class class1 = a1.getClass();

二、獲取Method物件

Method m1 = class1.getMethod("print", int.class, int.class);

原始碼中getMethod(String name, Class<?>... parameterTypes),第一個引數為方法的名稱,第二個是引數列表,在這我們可以通過兩種方法來表示

1、int.class, int.class

2、new Class[]{int.class, int.class}——》陣列的方式

這兩種方式結果都是一樣的。

三、通過Method物件呼叫invoke()方法

原始碼中invoke方法返回值預設是Object,如果通過反射操作的方法有返回值且不是Object,需要進行強制轉換;如果操作的物件沒有返回值型別,則返回null。

程式碼奉上:

/**
 * 方法的反射實際應用,即:通過類型別獲取方法物件,再通過方法物件進行反射操作。
 * 注:方法的名稱和引數列表唯一確定某一個方法
 * method.invoke(物件,引數)
 */
public class MethodReflectDemo {
    public static void main(String[] args) {
        A a1 = new A();
        //通過物件獲取類的類型別,可以獲取到類的資訊
        Class class1 = a1.getClass();
        //通過方法的名稱和引數列表唯一確定一個方法
        try {
            //通過getMethod()方法獲取方法物件,在這裡可以通過兩種方法獲取
//            Method me = class1.getMethod("print", new Class[]{int.class, int.class});
            Method me = class1.getMethod("print", int.class, int.class);
            //通過invoke()方法進行方法的反射操作,其是指通過Method物件對方法進行操作
            //invoke()其實是有返回值的,當方法如果沒有返回值型別(void)則返回null,如果有返回值型別則返回對應的返回值型別(預設是Object,需要做強制型別轉換)
//            Object object = me.invoke(a1, new Object[]{10,20});//傳遞陣列方式
            Object object = me.invoke(a1, 10,20);
            System.out.println("*************************");
//            Method me1 = class1.getMethod("print", new Class[]{String.class, String.class});
            Method me1 = class1.getMethod("print", String.class, String.class);
            object = me1.invoke(a1, "hello", "WORLD");
            System.out.println("*************************");
//            Method me2 = class1.getMethod("print", new Class[]{});
            Method me2 = class1.getMethod("print");
            object = me2.invoke(a1);
            System.out.println("*************************");
            Method m3 = class1.getMethod("print", String.class);
            String s = (String)m3.invoke(a1, "方法的反射操作");
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class A{
    public void print() {
        System.out.println("hello world");
    }
    public void print(int a, int b) {
        System.out.println(a+b);
    }
    public void print(String a, String b) {
        System.out.println(a.toUpperCase()+","+b.toLowerCase());
    }
    public String print(String s) {
        return s;
    }
}

輸出結果:

30
*************************
HELLO,world
*************************
hello world
*************************
方法的反射操作

 

我們在實際應用中的方法反射操作

一、已知一個實體類,通過屬性名,獲取其屬性值。實現的原理就是:通過字串拼接Javabean中的方法,進行方法反射方法的操作。

已知的實體類UserReflect。

public class UserReflect {
    private String name;
    private String sex;
    private int age;
    public UserReflect(String name, String sex, int age) {
        super();
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    public UserReflect() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    
}

封裝方法反射方法的操作

/**
 * 根據物件的屬性名獲取物件的屬性值。
 * 我們是通過字串拼接成javaBean裡的get方法名,然後通過方法反射執行方法。
 */
public class ReflectApplyMethod {
    public static Object getValueByPropertyName(Object object, String propertyName) {
        Object value = null;
        //拼接Javabean中的方法,得到方法名
        String action = "get"+propertyName.substring(0, 1).toUpperCase()+propertyName.substring(1);
        System.out.println("方法名:"+action);
        //通過已知物件object得到類型別
        Class class1 = object.getClass();
        //獲取Method物件,get方法都是public,所有使用getMethod()
        try {
            Method m = class1.getMethod(action);
            value = m.invoke(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
    
    public static void main(String[] args) {
        //主函式呼叫通過屬性名獲取屬性值的方法
        UserReflect uReflect = new UserReflect("Tom", "男", 20);
        System.out.println(getValueByPropertyName(uReflect, "name"));
        System.out.println(getValueByPropertyName(uReflect, "sex"));
        System.out.println(getValueByPropertyName(uReflect, "age"));
    }
}

主函式輸出結果:

方法名:getName
Tom
方法名:getSex

方法名:getAge
20