Home » Java

動態實體化物件並執行方法

因為工作上需要在執行時期動態載入類別並生成物件,操作物件上的方法甚至改變類別成員的值,所以找了些相關的內容的文章來看。

先寫一支MyDog.java的類別

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.abgne;
 
public class MyDog  {
 
    private String name;
    private int age;
 
    public MyDog() {
        name = "小白";
        age = 1;
    }
    public MyDog(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void setInfo(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void showInfo() {
        System.out.println("小狗名字是: " + name);
        System.out.println("小狗年齡是: " + age + " 歲");
    }
    public String toString(){
        return "小狗名字是: " + name + " 小狗年齡是: " + age + " 歲";
    }
}

若只要實體化物件的話,可以先取得Constructor後再來產生實體。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.abgne;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
 
public class NewInstanceSample {
 
    public static void main(String[] args) {
        try {
            Class c = Class.forName(args[0]);
            // 指定參數型態
            Class[] params = new Class[2];
            params[0] = String.class;
            params[1] = int.class;
            Constructor constructor = c.getConstructor(params);
            // 指定參數內容
            Object[] paramObjs = new Object[2];
            paramObjs[0] = args[1];
            paramObjs[1] = new Integer(args[2]);
            // 實體化class(透過建構子)
            Object classObj = constructor.newInstance(paramObjs);
            System.out.println(classObj);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }    
    }
}

醬在執行NewInstanceSample.class時就可以帶入參數且得到回應。

class_reflection_1

若是要實體化物件並執行該物件的方法時,則還要取得Method再Invoke。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.abgne;
 
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
 
public class InvokeMethodSample {
 
    public static void main(String[] args) {
        try {
            // 實體化class
            Class c = Class.forName(args[0]);
            Object classObj = c.newInstance();
            // 產生method並呼叫執行(有參數)
            Class[] params = {String.class, int.class};
            Method setInfo = c.getMethod("setInfo", params);
            Object[] paramObjs = {args[1],new Integer(args[2])};
            setInfo.invoke(classObj, paramObjs);
            // 產生method並呼叫執行(無參數)
            Method showInfo = c.getMethod("showInfo", null);
            showInfo.invoke(classObj, null);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

醬在執行NewInstanceSample.class時就可以帶入參數並執行方法。

class_reflection_2

用醬的方法就可以讓USER自訂class跟method,然後我們直接呼叫就可以使用了。

發表迴響