意義:
1.增加程序的靈活性,避免將程序寫死到代碼裏。
例:定義了一個接口,實現這個接口的類有20個,程序裏用到了這個實現類的地方有好多地方,如果不使用配置文件手寫的話,代碼的改動量很大,因爲每個地方都要改而且不容易定位,如果你在編寫之前先將接口與實現類的寫在配置文件裏,下次只需改配置文件,利用反射(java API已經封裝好了,直接用就可以用 Class.newInstance())就可完成。
2.代碼簡潔,提高代碼的複用率,外部調用方便
package cn.yonyong.reflection.testdemo;
interface Fruit { //水果接口
public void eat() ; //吃水果
}
class Apple implements Fruit{ //定義蘋果
public void eat() {
System.out.println("**吃蘋果。");
}
}
class Orange implements Fruit{
public void eat() {
System.out.println("**吃橘子。");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit fruit = null ;
try{
fruit = (Fruit) Class.forName(className).newInstance() ;
}catch(Exception e ){
e.printStackTrace() ;
}
return fruit ;
}
}
public class FactoryDemo{
public static void main(String args[]){
//通過工廠類取得接口實例,傳入完整的包.類名稱
Fruit f = Factory.getInstance("cn.yonyong.reflection.testdemo.Apple") ;
if(f!=null){ //判斷是否取得接口實例
f.eat() ;
}
}
}
如果不用反射,那麼我們如果再加一個西瓜類,就得在Factory裏判斷,每添加一個類都要修改一次Factory,但用了反射只用在調用的時候傳入完整的類名就可完成。結果:用反射,修改一處代碼;不用反射,修改兩處代碼。
3.對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法
反射的缺點
性能問題
1.使用反射基本上是一種解釋操作,用於字段和方法接入時要遠慢於直接代碼。因此Java反射機制主要應用在對靈活性和擴展性要求很高的系統框架上,普通程序不建議使用。
2.反射包括了一些動態類型,所以JVM無法對這些代碼進行優化。因此,反射操作的效率要比那些非反射操作低得多。我們應該避免在經常被 執行的代碼或對性能要求很高的程序中使用反射。
使用反射會模糊程序內部邏輯
程序人員希望在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,因而會帶來維護問題。反射代碼比相應的直接代碼更復雜。
安全限制
使用反射技術要求程序必須在一個沒有安全限制的環境中運行。如果一個程序必須在有安全限制的環境中運行,如Applet,那麼這就是個問題了
內部暴露
由於反射允許代碼執行一些在正常情況下不被允許的操作(比如訪問私有的屬性和方法),所以使用反射可能會導致意料之外的副作用--代碼有功能上的錯誤,降低可移植性。反射代碼破壞了抽象性,因此當平臺發生改變的時候,代碼的行爲就有可能也隨着變化。
Java反射可以訪問和修改私有成員變量,那封裝成private還有意義麼?
既然小偷可以訪問和搬走私有成員傢俱,那封裝成防盜門還有意義麼?這是一樣的道理,並且Java從應用層給我們提供了安全管理機制——安全管理器,每個Java應用都可以擁有自己的安全管理器,它會在運行階段檢查需要保護的資源的訪問權限及其它規定的操作權限,保護系統免受惡意操作攻擊,以達到系統的安全策略。所以其實反射在使用時,內部有安全控制,如果安全設置禁止了這些,那麼反射機制就無法訪問私有成員。
反射是否真的會讓你的程序性能降低?
1.反射大概比直接調用慢50~100倍,但是需要你在執行100萬遍的時候纔會有所感覺
2.判斷一個函數的性能,你需要把這個函數執行100萬遍甚至1000萬遍
3.如果你只是偶爾調用一下反射,請忘記反射帶來的性能影響
4.如果你需要大量調用反射,請考慮緩存。
5.你的編程的思想纔是限制你程序性能的最主要的因素