什么是java反射機制?
1、當程序運行時,允許改變程序結構或變量類型,這種語言稱為動態語言。我們認為java並不是動態語言,但是它卻有一個非常突出的動態相關機制,俗稱:反射。
IT行業里這么說,沒有反射也就沒有框架,現有的框架都是以反射為基礎。在實際項目開發中,用的最多的是框架,填的最多的是類,反射這一概念就是將框架和類揉在一起的調和劑。所以,反射才是接觸項目開發的敲門磚。
2、java中的new方法是靜態加載,因為new方法是在編譯階段就會檢查,而不是在運行階段。反射是可以在運行時創建對象,調用對象的方法、變量等。
3、Java反射機制主要提供了以下功能:在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法;在運行時調用任意一個對象的方法;生成動態代理。
例如:
1 package service.impl; 2 3 public class Test { 4 5 public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { 6 F f = new F(); 7 // 第一種表達方式 8 Class c1 = F.class;// 這種表達方式同時也告訴了我們任何一個類都有一個隱含的靜態成員變量class 9 // 第二種表達方式 10 Class c2 = f.getClass();// 這種表達方式在已知了該類的對象的情況下通過getClass方法獲取 11 // 第三種表達方式 12 Class c3 = Class.forName("service.impl.F");// 類的全稱 13 14 System.out.println(c1.getName()); 15 System.out.println(c2.getName()); 16 System.out.println(c3.getName()); 17 F temp = (F) c1.newInstance();//這里可以是c1/c2/c3 18 System.out.println(temp.f); 19 temp.save(); 20 } 21 } 22 23 class F { 24 public String f = "test"; 25 26 public void save() { 27 System.out.println("save..."); 28 } 29 }
運行結果:
service.impl.F
service.impl.F
service.impl.F
test
save...
動態加載:
如何動態加載一個類呢?
首先我們需要區分什么是動態加載?什么是靜態加載?我們普遍認為編譯時刻加載的類是靜態加載類,運行時刻加載的類是動態加載類。
例如:
1 Class A{ 2 Public static void main(String[] args){ 3 if("B".equal(args[0])){ 4 B b=new B(); 5 b.start(); 6 } 7 if("C".equal(args[0])){ 8 C c=new C(); 9 C.start(); 10 } 11 } 12 }
上面程序編譯時會報錯,當我們直接在cmd使用javac訪問A.java類的時候,就會拋出問題:
但是如果我們動態加載就可以滿足(參數不為“B”或者“C”時候,本應該可以運行)
如:
1 package service.impl; 2 3 public class Test2 { 4 5 public static void main(String[] args) throws InstantiationException, IllegalAccessException { 6 7 Class b = null; 8 try { 9 b = Class.forName("service.impl.B"); 10 } catch (ClassNotFoundException e) { 11 System.err.println("something is wrong!!!"); 12 e.printStackTrace(); 13 } 14 Stand stand = (Stand)b.newInstance(); 15 stand.start(); 16 17 } 18 } 19 20 interface Stand{ 21 void start(); 22 } 23 24 class B implements Stand{ 25 26 public void start() { 27 System.out.println("B...start"); 28 } 29 30 } 31 32 class C implements Stand{ 33 34 public void start() { 35 System.out.println("C...start"); 36 } 37 38 }
運行結果:
B...start
如果以后想用某一個類,不需要重新編譯,只需要實現這個標准的接口即可。只需要動態的加載新的東西就行了。
這就是動態加載類
