出處:
1、反射的作用:
反射是一種底層程式設計(通用程式設計),利用反射可以寫出非常通用的**
日常例項:
在eclipse中,當輸入類名.方法名的一部分時,
整個方法名就會出現在備選框中,這種功能就利用到了反射
2、反射的應用範圍:
開發工具的編寫(例如eclipse之類的開發工具)
程式框架的開發(例如開發乙個模仿structs的架構)等。
3、反射的例子:(請考慮下面三個方法的實現)
static void printmethods(string classname) throws exception
要求:方法的引數為類名,方法的返回值為該類下所有的公開方法
static object createobject(string classname) throws exception
要求:方法的引數為類名,返回值為乙個通過該類的無參構造方法生成的物件
static void methodinvoke(object o,string methodname) throws exception
要求:方法的引數是物件和物件的方法名,然後在方法體內部呼叫該物件的相應方法
4、反射的關鍵:類物件
*類的載入:
當虛擬機器要用到乙個類的時候
由於虛擬機器內部還沒有該類的資訊
因此虛擬機器不知道該如何使用這個類
於是虛擬機器需要首先通過classpath找到相應的類
並通過 類載入器進行載入(類似於inputstream向虛擬機器內部讀取)
當這個類被載入到虛擬機器中時,必須要儲存起來
儲存的方式就是:虛擬機器需要建立乙個該類的物件,用於封裝該類的所有資訊
這個被建立的該類的物件,就稱作類物件
因此,類物件就是用於描述乙個類,並且封裝了該類內部所有資訊的物件
****用於建立類物件以封裝類內部資訊的類就是:
class
類****
模擬:在動物園中,認識的任何動物都只是一類動物,而不是某乙隻動物
例如,當不認識狼的時候,就需要在附近尋找說明牌以了解狼類
當通過了牌子認識了狼類後,以後再遇到狼類則不再需要讀牌子
所以說,牌子就是封裝了狼類的資訊的乙個具體物件,
而牌子本身又是乙個類
因此:一塊牌子就是封裝了狼類的資訊的類的乙個物件,
而一條狼是狼類的乙個物件
5、獲得類物件的方法:
例如:arraylist list = new arraylist();
方法1:class c1 = arraylist.class;
//通過類名.class取得該類的類物件
方法2:class c2 = list.getclass();
//通過該類的物件.getclass()取得該類的類物件
方法3:class c3 = class.forname("arraylist");
(注意雙引號)
//通過class類的forname("classname")方法取得該類的類物件
*若不需要返回值,forname方法也可用於強制使虛擬機器載入乙個類
6、類物件(class)的常用方法:
(object) o = c.newinstance(); //建立該類的乙個物件
string name = c.getname() //獲得該類的類名,返回string物件
class super = c.getsuperclass() //獲得該類的父類的類物件,返回class物件
class inte***ce = c.getinte***ces() //獲得該類物件實現的所有介面,返回class陣列
(因為介面的資訊也是封裝在類物件中的)
-------------------用於方便閱讀的華麗的分界線1-------------------
*與class作用類似的類(屬於reflect包的類):
field:用於封裝某個類中所有屬性資訊的物件
method:用於封裝某個類中所有方法
資訊的物件
constructor:用於封裝某個類中所有的構造方法
資訊的物件
field fields1 = c.getdeclaredfields(); //獲得該類的所有屬性
field fields2 = c.getfields(); //獲得該類的所有非private屬性
method ms1 = c.getdeclaredmethods(); //獲得該類的所有方法
method ms2 = c.getmethods(); //獲得該類的所有非private方法
constructor cons1=c.getdeclaredconstructors(); //獲得該類的所有構造方法
constructor cons2=c.getconstructors(); //獲得該類的所有非private構造方法
****getdeclared***()與get***()的區別****
以method為例:
c.getdeclaredmethods();方法的返回值為該類中包括private修飾的所有方法,但是不包括父類中的方法
c.getmethods();方法的返回值為該類中以及父類中的所有方法,但是不包括private修飾的方法
-------------------用於方便閱讀的華麗的分界線2-------------------
method m = c.getdeclaredmethod(string methodname);
//獲得類物件c中方法名為methodname,引數為空的方法
method m = c.getdeclaredmethod(string methodname, class para);
//獲得類物件c中方法名為methodname,引數為para的類的方法
7、反射例子的實現(例子見3):
1、方法的引數為類名,方法的返回值為該類下所有的公開方法
實現:static void printmethods(string classname) throws exception //遍歷該陣列
}2、方法的引數為類名,返回值為乙個通過該類的無參構造方法生成的物件
實現:static object createobject(string classname) throws exception
3、方法的引數是物件和物件的方法名,然後在方法體內部呼叫該物件的相應方法
實現:static void methodinvoke(object o, string methodname, object parameter) throws exception
8、反射作為底層技術的最大優勢:
由於反射是一種特別底層的技術,而資訊的隱藏是構建於反射層面之上的,因此反射可以直接破壞資訊的隱藏,例如;
//強制呼叫testclass中用private修飾的hidden()方法:
class testclass //設定此方法為只有該類自身能夠訪問
}public class testreflect
}9、反射濫用的缺點:
-1、破壞了資訊隱藏
-2、降低了程式的執行效率以及可讀性
-3、讓程式中的異常由編譯時丟擲推遲到了執行時丟擲,降低了程式的安全性(即:把編譯器應當做的工作讓虛擬機器去做)
Java基礎之反射
1.反射 將類的各個組成部分封裝為其他物件,這就是反射機制 好處 1.可以在程式執行過程中,操作這些物件 2.可以解耦,提高程式的可擴充套件性 2.獲取class物件的幾種方式 1.class.forname 全類名 將位元組碼檔案載入進來,返回class物件 2.類名.class 通過類名的屬性c...
Java之列舉篇
出處 1 為什麼要出現列舉 在現實生活中,有許多實體有且僅有特定的幾個屬性 例如 月份只有1 12月,性別只有男女,季節只有四季 等 若將其型別定義成常量,則不可避免地出現非法引數的問題 例如 13月,第三個性別,第五個季節 等 因此,對於上述型別的物件,必須規定其特定的屬性值為列舉型別,即 僅能從...
C 反射之跨空間Load Enum篇
c 反射只能夠load本名字空間以及mscore.dll空間的型別,如果需要獲得某dll中型別,必須通過如下載入assembly然後才能獲取到相應的型別 assembly assembly assembly.load xdll.dll type type assembly.gettype mydll...