02.04 學了這麼多年java原來這就是java的反射和動態加載類

這裡先介紹一些概念請大家不要暈

反射機制概念

主要是指程序可以訪問,檢測和修改它本身狀態或行為的一種能力,並能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。在java中,只要給定類的名字, 那麼就可以通過反射機制來獲得類的所有信息。

反射是Java中一種強大的工具,能夠使我們很方便的創建靈活的代碼,這些代碼可以再運行時裝配,無需在組件之間進行源代碼鏈接。但是反射使用不當會成本很高!

類中有什麼信息,利用反射機制就能可以獲得什麼信息,不過前提是得知道類的名字。

反射機制的作用

  1. 在運行時判斷任意一個對象所屬的類;

  2. 在運行時獲取類的對象;

  3. 在運行時訪問java對象的屬性,方法,構造方法等。

反射機制的優點與缺點

首先要搞清楚為什麼要用反射機制?直接創建對象不就可以了嗎,這就涉及到了動態與靜態的概念。

靜態編譯:在編譯時確定類型,綁定對象,即通過。

學了這麼多年java原來這就是java的反射和動態加載類

這裡我們通過new進行相關類的實例化,這裡如果new的類是不存在的會編譯不通過,因為靜態需要預先加載進去

如果不存在的話加載不進去也就會報錯

假想如下場景,此類中有100個功能,你只想使用A功能,如果你使用的是靜態加載的機制,你必須定義其餘的99種功能才能使用A功能,如果使用動態加載機制,不僅不用定義99中功能,通過實現某種標準(繼承某個接口),將大大方便了代碼的編寫。

動態編譯:運行時確定類型,綁定對象。動態編譯最大限度發揮了java的靈活性,體現了多態的應用,有以降低類之間的藕合性。

public class StaticClassDemo2 {
public static void main(String[] args) {
try {
Class c=Class.forName(args[0]);
NewStandard me=(NewStandard)c.newInstance();
me.print();
} catch (Exception e) {
e.printStackTrace();}}

學了這麼多年java原來這就是java的反射和動態加載類

public interface NewStandard {
public void print();
}
public class TestA implements NewStandard {
@Override
public void print() {
System.out.println("TestA...print");
}
public class TestB implements NewStandard{
@Override
public void print() {
System.out.println("TestB....print");
}

這時候我們使用一個此類就可以完成對所有的功能的引用而不用每一個都去創建

反射機制的優點:可以實現動態創建對象和編譯,體現出很大的靈活性(特別是在J2EE的開發中它的靈活性就表現的十分明顯)。通過反射機制我們可以獲得類的各種內容,進行了反編譯。對於JAVA這種先編譯再運行的語言來說,反射機制可以使代碼更加靈活,更加容易實現面向對象。

比如,一個大型的軟件,不可能一次就把把它設計的很完美,當這個程序編譯後,發佈了,當發現需要更新某些功能時,我們不可能要用戶把以前的卸載,再重新安裝新的版本,假如這樣的話,這個軟件肯定是沒有多少人用的。採用靜態的話,需要把整個程序重新編譯一次才可以實現功能的更新,而採用反射機制的話,它就可以不用卸載,只需要在運行時才動態的創建和編譯,就可以實現該功能。

反射機制的缺點:對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什麼並且它 滿足我們的要求。這類操作總是慢於只直接執行相同的操作。

最能以簡單的例子體現反射的強大之處,但是又感覺沒有太具體,在自己思考了許久後,終於想到一個體現這個場景的簡單例子。

不用反射:

假設有個生產環境,數據庫連接是用的mysql,所以代碼應該是這樣 ,以偽代碼書寫,忽略細節

conn =new MysqlConnection()

然而,某一天突然要改成oracle。所以,這時要做的是改成

conn =new OracleConnection()

或者你機靈一點,新建一個配置文件,裡面填mysql或oracle,然後代碼中取得配置文件的字符串,if是 mysql就 conn =new MysqlConnection() 是oracle就 conn =new OracleConnection,

然後。最重要的是。你要停掉生產環境,重新把java代碼用javac編譯一遍,再把編譯後的class文件把生產環境給起起來。

讓我們再來看看用反射,

最開始,如果我們就考慮到會有時切換數據庫,我們寫成配置文件,然後用Class.forName(str)什麼的來new 數據庫驅動,更改數據庫時就僅需簡單的更改配置文件了,這樣就不需要重新編譯代碼了,但好像還需要重新啟動生產環境。哦,如果想不重新啟動生產環境來切換數據庫也是可以的(不考慮任何效率),自行造輪子咯。

這裡用反射和不用反射的區別在於,是否要重新編譯一遍

學了這麼多年java原來這就是java的反射和動態加載類


分享到:


相關文章: