java基礎-反射技術(磨礪營馬劍威java)

?

在Java運行時環境中,對于任意一個類,能否知道這個類的哪些屬性和方法?對于任意一個對象,能否調用它的任意一個方法?答案是肯定的。這種動態獲取類的信息以及動態調用對象的方法的功能來自于Java語言的反射(Reflection)機制。

反射給java提供了,運行時獲取一個類實例的可能,這一點非常靈活,你僅僅傳一個類的全限定名,就能通過反射,來獲取對應的類實例,我們一般會用Class類,來調用這個被反射的Objcet類下的:構造方法,屬性,或方法等。

反射在一些開源框架里用的非常之多,Spring,Struts,Hibnerate,MyBatics都有它的影子,反射雖然很靈活,能夠使得寫的代碼,變的大幅精簡,所以在用的時候,一定要注意具體的應用場景。

反射的優缺點如下:

優點:

A:能夠運行時動態獲取類的實例,大大提高系統的靈活性和擴展性。

B:與Java動態編譯相結合,可以實現無比強大的功能

缺點:

A:使用反射的性能較低

B:使用反射相對來說不安全

C:破壞了類的封裝性,可以通過反射獲取這個類的私有方法和屬性

任何事物,都有兩面性,反射的優點,也同是就是它的缺點,所以,沒有好與壞,只有最合適的場景,一陰一陽,才是天道平衡的條件。

在反射API中我們重點關注一下幾個類:

Class? -- 代表類

Field? -- 代表屬性(成員變量)

Method? -- 代表方法

Constructor? -- 代表構造方法

一、Class

Java中不論一個類產生了多少個對象,這些對象的Class對象都始終是一個。Class對象中含有該類的任何信息(屬性,方法,類名,父類,包等),在Java中獲取Class對象的方法有三種:

// 第一種方法:類名.class

Class ? cla = Student.class;

Class ? as =int.class;?? // 基本數據類型唯一能點出的就是class

// 第二種方法:通過對象調用.getClass()

Student ? stu =newStudent();

Class ? c = stu.getClass();

// 第三種方法:通過類的全限定名獲取

try{

Class ? c1 = Class.forName("entity.Student");

}catch(ClassNotFoundException e) {

e.printStackTrace();

}

System.out.println(cla.getName()); // 全限定名

System.out.println(Modifier.toString(cla.getModifiers()));

System.out.println(cla.getSimpleName());

System.out.println(cla.getPackage().getName());

可以通過Class對象產生該類的對象,如下:

// 獲取Class對象

Class ? cla = Student.class;

/* 1. 直接創建對象(調用默認無參構造方法),類里必須要有默認構造方法 */

Object ? obj1 = cla.newInstance();

System.out.println(obj1);

二、Constructor

如果想通過有參構造方法來創建對象,那么這時候就得先獲取有參構造方法,再通過有參構造方法來創建對象:

// 獲取Class對象

Class cla = Student.class;

/* 1. 直接創建對象(調用默認無參構造方法),類里必須要有默認構造方法 */

Object obj1 = cla.newInstance();

System.out.println(obj1);

/* 2. 通過無參構造方法創建對象,和第一種方法效果一樣 */

Constructor no = cla.getConstructor(); // 先獲取無參構造方法

Object obj2 = no.newInstance();

System.out.println(obj2);

/* 3. 通過有參構造方法創建對象 */

Constructor has = cla.getDeclaredConstructor(String.class,int.class); // 形參

Object obj3 = has.newInstance("老李", 23); // 傳入的是實參

System.out.println(obj3);

三、Field

Field代表是類中的屬性,我們可以獲取屬性,并修改其值(注:先得有對象才能修改值,另:修改沒權限的屬性時,需要先打開該屬性的權限)。

// 獲取Class對象

Class cla =newStudent().getClass();

// 獲取構造方法

Constructor con = cla.getConstructor(String.class,int.class);

// 創建對象

Object obj = con.newInstance("如來", 222);

// 獲取要操作的屬性

Field name = cla.getDeclaredField("name");

// 反射操作private屬性的時候,需要打開權限

name.setAccessible(true);

// 獲取obj的name屬性值

System.out.println(name.get(obj));

// 把obj的name屬性值改為:菩提

name.set(obj, "菩提");

System.out.println(name.get(obj));

// 把id設置為10086

Field id = cla.getDeclaredField("id");

id.set(obj, 10086);

System.out.println(id.get(obj))

四、Method

Method代表類中的方法,和Field操作類型:

// 獲取Class對象

Class cla = Student.class;

// 創建對象

Object obj = cla.getDeclaredConstructor(String.class,int.class).newInstance("達摩", 666);

// 獲取要操作的方法

Method showNo = cla.getDeclaredMethod("show");

Method showHas = cla.getDeclaredMethod("show", String.class);

Method calc = cla.getDeclaredMethod("calc",int.class,double.class);

calc.setAccessible(true);

// 調用方法

showNo.invoke(obj);

showHas.invoke(obj, "老衲");

Object value = calc.invoke(obj, 10086, Math.PI);

System.out.println(value);

我們可以用反射來改進簡單工廠模式:

packagedemo08;

importjava.io.FileInputStream;

importjava.util.Properties;

publicclassPetFactory {

publicstaticvoidmain(String[] args) {

System.out.println(getInstance("dog")); ?// demo08.Dog@67a9b034

}

// 工廠方法

publicstaticPet ? getInstance(String tag) {

Properties ? p =newProperties();

try{

p.load(newFileInputStream("conf/pet.properties"));

}catch(Exception e) {

System.out.println("加載配置文件錯誤!");

}

String ? className = p.getProperty(tag);

try{

// 利用反射創建對象

Class ? cla = Class.forName(className);

return(Pet)cla.newInstance();

}catch(ClassNotFoundException e) {

System.out.println("無法識別您的標識!");

}catch(InstantiationException e) {

e.printStackTrace();

}catch(IllegalAccessException e) {

e.printStackTrace();

}

returnnull;

}

}

classPet {}

classDogextendsPet {}

classCatextendsPet {}

classPenguinextendsPet {}

conf/pet.properties文件內容如下:

dog=demo08.Dog

cat=demo08.Cat

penguin=demo08.Penguin

這里的配置文件為.properties,稱作屬性文件。通過反射讀取里邊的內容。這樣代碼是固定的,但是配置文件的內容我們可以改,這樣使我們的代碼靈活了很多!

綜上JAVA反射的再次學習,靈活的運用它,能夠使我們的代碼更加靈活,但是它也有它的缺點,就是運用它會使我們的軟件的性能降低,復雜度增加,所以還要我們慎重的使用它。

更多內容關注微信公眾號mjw-java或訪問www.moliying.com

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,722評論 18 399
  • 一、概述 Java反射機制定義 Java反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類中的所有屬性和方法...
    CoderZS閱讀 1,647評論 0 26
  • 1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以讓我們在運行時獲取類的函數、...
    Ten_Minutes閱讀 546評論 0 4
  • (一)Java部分 1、列舉出JAVA中6個比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨云閱讀 7,129評論 0 62
  • 1.jdbc是什么,它有什么用? java database connection 讓java程序員可以直接通過j...
    yeller閱讀 575評論 0 2