整理一下大二所做的手抄筆記1(反射機制及為什麼要使用反射)
本來想就“大三筆記”這個專欄一直寫下去的,後來想想,很多現在接觸到的知識都是需要了解一下底層原理才能更好地掌握的,於是乎,鞭策鞭策自己,將自己大二期間作的手抄筆記慢慢都更新到csdn中,方便閱覽,當然了,“大三筆記”也是會一直更的,期間也會更這個專欄。
什麼是反射
JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的位元組碼檔案物件。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼檔案對應的Class型別的物件.
class Office{
public static void main(String []args){
if(args[0].equals("word")){
word w = new word();
w.start();
}
if(args[0].equals("excel")){
excel e = new excel();
e.start();
}
}
假如我們想要執行office類,那麼我們是否一定要建立word和excel類? 如果我們不採用反射機制,那麼答案就是肯定的,我們必須建立word和excel,但是呢,假如我們實際上只想呼叫word裡面的start方法呢?
可能有小夥伴說,那我們便建立一個word類唄。
class word{
public void start("word start..");
}
javac office.java
java office word
如上圖所示,我們將"word"作為arg[0]傳進去,然後執行office,可以執行嗎? 不行,其實實際上編譯都無法通過,因為會報classnotfoundexception,找不到excel。相信大家已經察覺到問題了吧?我明明只想呼叫word裡面的方法,excel方法我暫時不想用,我的理想狀態是我想用word的時候就只加載word,到我用excel的時候你再來報錯
這裡的關鍵點是:我們通過new出來的例項物件,是屬於靜態編譯,在編譯時就需要載入所有類中可能會用到的類,如果找不到類則報錯,那如何解決? 沒錯,動態編譯。
請大家弄清一個概念:
編譯時刻載入類是靜態載入類,執行時刻載入類是動態載入類。
下面我們來寫一個能夠動態載入類的office類。
class OfficeBetter{
public static void main(String []args){
try{
//動態載入類,在執行時刻載入
Class c = Class.forName(args[0]);
word w = (word)c.newInstance();
w.start();
}
catch(Exception e){...}
}}
這樣寫有問題嗎? 有的,因為這樣子雖然是動態載入了,可是你這跟excel沒有關係了呀,萬一我又突然想呼叫excel裡面的方法呢?難道我要把c.newInstance()強轉為excel,然後再編譯? 別急,下面請看。
interfacce officeAble{
public void start();
}
class OfficeBetter{
public static void main(String []args){
try{
//動態載入類,在執行時刻載入
Class c = Class.forName(args[0]);
OfficeAble oa = (OfficeAble)c.newInstance();
oa.start();
}
catch(Exception e){...}
}}
沒錯,相信大家也已經明白了---讓word和excel實現officeable介面,這樣你不管傳的args[0]是word還是excel,或者是你以後想擴充套件一些類,你大可以新建一個任意類,只要它實現了officeable介面,你就可以在officeBetter中呼叫。