使用反射產生並操作對象

來源:互聯網
上載者:User

標籤:

一、擷取Class對象的方式

Java中,每個類被載入到記憶體中,系統就會為該類產生一個對應的Class對象,通過該Class對象就可以訪問到JVM中的這個類,獲得Class對象有三種方式:

1.使用Class類的forName(String clazzName)靜態方法,該方法需要傳入字串參數,該字串參數的值是某個類的全限定類名。

2.通過某個類的class屬性擷取,例如Person.class。

3.調用某個對象的getClass()方法。該方法是java.lang.Object類中的一個方法,所以所有的Java對象都可以調用該方法,該方法將會返回該對象所屬類對應的Class對象。

對於第一種和第二種方法,都是直接根據類來取得該類的Class對象,相比之下,第二種方式有以下優勢:

代碼更安全,程式在編譯階段就可以檢查需要訪問的Class對象是否存在。

程式效能更好,因為這種方式無需調用方法。

二、通過反射建立對象的方式

有兩種方式:

1.使用Class對象的newInstance()方法來建立該Class對象對應類的執行個體,這種方式要求該Class對象的對應類有預設構造器,而執行newInstance()方法時實際上是利用預設構造器來建立該類的執行個體。

2.先使用Class對象擷取指定的Constructor對象,再調用Constructor對象的newInstance()方法來建立該Class對象對應類的執行個體。

三、調用方法

當獲得某個類對應的Class對象後,就可以通過該Class對象的getMethods()方法或者getMethod()方法來擷取全部方法或者指定方法。

每個Method對象對應一個方法,獲得Method對象後,程式就可通過該Method來調用它對應的方法,在Method裡麵包含一個invoke()方法,該方法的簽名如下:

Object invoke(Object obj,Object... args):該方法中的obj是執行該方法的主調,後面的args是執行該方法時傳入該方法的實參。

下面寫一個例子,對象池工廠,簡單類比一下Spring架構的IoC思想。

obj.txt中:

a=java.util.Dateb=javax.swing.JFrameb%title=Title

主代碼:

package demo;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import java.util.Properties;public class ObjectPoolFactory {    //定義一個對象池    private Map<String, Object> objectPool = new HashMap<String, Object>();    private Properties props = new Properties();        /**     * 定義一個建立對象的方法     * @param clazzName     * @return     * @throws ClassNotFoundException     * @throws InstantiationException     * @throws IllegalAccessException     */    private Object createObject(String clazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException{        //根據字串擷取對應的class對象        Class clazz = Class.forName(clazzName);        //使用clazz對應類的預設構造器建立執行個體        return clazz.newInstance();    }        /**     * 初始化properties對象     * @param fileName     * @throws IOException     */    public void init(String fileName) throws IOException{        FileInputStream fis = new FileInputStream(fileName);        props.load(fis);    }        /**     * 根據指定檔案來初始化對象池     * 它會根據設定檔來建立對象     * @throws IOException      * @throws IllegalAccessException      * @throws InstantiationException      * @throws ClassNotFoundException      */    public void initPool() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException{                for (String name : props.stringPropertyNames()) {            //每取出一對key-value對,就根據value建立一個對象            //調用createObject()建立對象,並將對象添加到對象池中            System.out.println(name);            if(!name.contains("%")){                objectPool.put(name, createObject(props.getProperty(name)));            }        }    }        /**     * 該方法根據屬性檔案來調用指定對象的setter方法     * @throws SecurityException      * @throws NoSuchMethodException      * @throws InvocationTargetException      * @throws IllegalArgumentException      * @throws IllegalAccessException      */    public void initProperty() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{        for (String name : props.stringPropertyNames()) {            //key用於控制對象的setter方法設定值            //%前面是對象名字,後面是setter方法名            if(name.contains("%")){                String[] strs = name.split("%");                Object target = getObject(strs[0]);                String method = "set" + strs[1].substring(0, 1).toUpperCase() +                        strs[1].substring(1);                //擷取對象實作類別多對應的Class對象                Class targetClass = target.getClass();                //擷取希望調用的setter方法                Method mtd = targetClass.getMethod(method, String.class);                //通過Method的invoke方法執行setter方法                mtd.invoke(target, props.getProperty(name));            }        }    }        /**     * 擷取對象     */    public Object getObject(String name){        //從objectPool中取出指定name對應的對象        return objectPool.get(name);    }        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {        ObjectPoolFactory pf = new ObjectPoolFactory();        pf.init("obj.txt");        pf.initPool();        pf.initProperty();        System.out.println(pf.getObject("a"));        System.out.println(pf.getObject("b"));    }        }

運行結果:

bab%titleWed Apr 27 21:51:20 CST 2016javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=Title,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

視窗的名字也傳進來了,說明調用setter方法成功。

 

使用反射產生並操作對象

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.