具體的關於反射的介紹可以參考我的另外一篇博文《深入解析java反射》。
反射的意義是什么,其實就是為了代碼簡潔,提高代碼的復用率,外部調用方便,源代碼,反編譯都能看到。
某些情況下解耦用反射要清晰很多,下面是簡單的測試
1 package cn.yonyong.reflection.testdemo; 2 3 interface Fruit { //水果接口 4 public void eat() ; //吃水果 5 } 6 7 class Apple implements Fruit{ //定義蘋果 8 public void eat() { 9 System.out.println("**吃蘋果。"); 10 } 11 } 12 13 class Orange implements Fruit{ 14 public void eat() { 15 System.out.println("**吃橘子。"); 16 } 17 } 18 19 class Factory{ 20 public static Fruit getInstance(String className){ 21 Fruit fruit = null ; 22 try{ 23 fruit = (Fruit) Class.forName(className).newInstance() ; 24 }catch(Exception e ){ 25 e.printStackTrace() ; 26 } 27 return fruit ; 28 } 29 } 30 31 public class FactoryDemo{ 32 public static void main(String args[]){ 33 //通過工廠類取得接口實例,傳入完整的包.類名稱 34 Fruit f = Factory.getInstance("cn.yonyong.reflection.testdemo.Apple") ; 35 if(f!=null){ //判斷是否取得接口實例 36 f.eat() ; 37 } 38 } 39 }
輸出:
**吃蘋果。
如果不用反射,那么我們如果再加一個西瓜類,就得在Factory里判斷,每添加一個類都要修改一次Factory,但用了反射只用在調用的時候傳入完整的類名就可完成。結果:用反射,修改一處代碼;不用反射,修改兩處代碼。
但是,我們知道java面向對象主要有四大特性:
封裝、抽象、繼承和多態。
封裝:在面向對象語言中,封裝特性是由類來體現的,我們將現實生活中的一類實體定義成類,其中包括屬性和行為(在Java中就是方法),就好像人類,可以具有name,sex,age等屬性,同時也具有eat(),sleep()等行為,我們在行為中實現一定的功能,也可操作屬性,這是面向對象的封裝特性;
抽象:抽象就是將一類實體的共同特性抽象出來,封裝在一個抽象類中,所以抽象在面向對象語言是由抽象類來體現的。比如鳥就是一個抽象實體,因為抽象實體並不是一個真正的對象,它的屬性還不能完全描述一個對象,所以在語言中體現為抽象類不能實例化;
繼承:繼承就像是我們現實生活中的父子關系,兒子可以遺傳父親的一些特性,在面向對象語言中,就是一個類可以繼承另一個類的一些特性,從而可以代碼重用,其實繼承體現的是is-a關系,父類同子類在本質上還是一類實體;
多態:多態就是通過傳遞給父類對象引用不同的子類對象從而表現出不同的行為 ...
那么既然Java反射可以訪問和修改私有成員變量,那封裝成private還有意義么?
既然小偷可以訪問和搬走私有成員家具,那封裝成防盜門還有意義么?這是一樣的道理,並且Java從應用層給我們提供了安全管理機制——安全管理器,每個Java應用都可以擁有自己的安全管理器,它會在運行階段檢查需要保護的資源的訪問權限及其它規定的操作權限,保護系統免受惡意操作攻擊,以達到系統的安全策略。所以其實反射在使用時,內部有安全控制,如果安全設置禁止了這些,那么反射機制就無法訪問私有成員。