java反射機制

JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意方法和屬性;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為java語言的反射機制。“反”,就要先了解“正”。一般先知道類,然后通過類產(chǎn)生實例化對象,而反射是通過對象找類。
反射機制一般用在框架類代碼編寫,所以平時在框架基礎(chǔ)上開發(fā)特性時一般用的比較少。
Class類是反射機制的基礎(chǔ)。反射機制是跟spring 和bean的基礎(chǔ)。

優(yōu)點:

使得系統(tǒng)框架具有高度的靈活性和擴展性。(反射是框架設(shè)計的靈魂)

缺點:

1)可能引入性能問題
2)使得程序的邏輯不再直觀
3)可移植性,因為反射依賴于java本身框架支持,如果移植到類似andriod平臺可能就支持的不好。
4)多線程高并發(fā)環(huán)境下可能引入問題。
所以,任何語言特性都不能濫用,要考慮是否需要另一種更合適的語言。

很多設(shè)計模式使用java的反射機制實現(xiàn)非常方便,甚至連客戶端的代碼都不需要修改。例如下面的簡單工廠的實現(xiàn),不需要停運行環(huán)境,只需要改配置文件即可實現(xiàn)不同類的生產(chǎn)。

import java.io.*;
import java.lang.reflect.InvocationTargetException;

class Animal {
    void MyPrint(String str) {
        System.out.println(str);
    }

    void Show() {
        MyPrint("I'm Animal");
    }
}

class Dog extends Animal {
    @Override
    void Show() {
        MyPrint("I'm Dog");
    }
}

class Cat extends Animal {
    @Override
    void Show() {
        MyPrint("I'm Cat");
    }
}

class AnimalFactory {
    private static AnimalFactory factory = new AnimalFactory();
    private AnimalFactory() {}

    static AnimalFactory GetInst() {
        return factory;
    }

    Animal Create() {
        try {
            // 替換成你自己的文件路徑
            File file = new File("C:\\Users\\Administrator\\IdeaProjects\\demo2\\src\\test.txt");
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String animalName = reader.readLine();
            Class<?> clazz = Class.forName(animalName);
            Object obj = clazz.getDeclaredConstructors()[0].newInstance();
            reader.close();
            return (Animal) obj;
            // 忽略異常處理
        } catch (IOException e) {

        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {

        } catch (ClassNotFoundException e) {

        }
        return null;
    }
}

你可以在執(zhí)行過程中修改test.txt文件,可以看到工廠創(chuàng)建的類在及時地變化,而不需要重新編譯代碼,甚至不需要重新啟動程序。

I'm Cat
I'm Cat
I'm Cat
I'm Dog

重要的是要意識到反射沒有什么魔力。當你使用反射與未知類型的對象交互時,JVM 將查看該對象,并看到它屬于特定的類(就像普通的 RTTI)。在對其執(zhí)行任何操作之前,必須加載 Class 對象。因此,該特定類型的 .class 文件必須在本地計算機上或通過網(wǎng)絡(luò)對 JVM 仍然可用。因此,RTTI 和反射的真正區(qū)別在于,使用 RTTI 時,編譯器在編譯時會打開并檢查 .class 文件。換句話說,你可以用“正常”的方式調(diào)用一個對象的所有方法。通過反射,.class 文件在編譯時不可用;它由運行時環(huán)境打開并檢查。

反射機制的應(yīng)用場景:序列化,文檔提?。ㄒ婎惙椒ㄌ崛∑鳎?/p>

示例代碼倉庫:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容