Java反射技術應用廣泛,其能夠配置:類的全限定名,方法和參數,完成對象的初始化,設置是反射某些方法。可以增強java的可配置性。
1.1 通過反射構建對象(無參數):
例如我們使用 ReflectServiceImpl 類講解這個例子
1 public class ReflectServiceImpl { 2 public void sayHello(String name){ 3 System.out.println("hello"+name); 4 } 5 }
我們通過反射的方法去構建它。
1 public ReflectServiceImpl getInstance(){ 2 ReflectServiceImpl object=null; 3 try { 4 object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance(); 5 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 return object; 9 }
其中第4行:object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
是給類加載器注冊一個類ReflectServiceImpl的權限定名,之后通過newInstance方法初始化一個類對象。
1.2 通過反射構建對象(類的構造器中帶有參數):
我們使用ReflectServiceImpl2這個類去理解:
1 public class ReflectServiceImpl2 { 2 private String name; 3 public ReflectServiceImpl2(String name) { 4 this.name=name; 5 } 6 public void sayHello(String name){ 7 System.out.println("hello"+name); 8 } 9 }
此時 ReflectServiceImpl2的構造器帶有參數 public ReflectServiceImpl2(String name){xxxx};
此時我們該如何利用反射生成對象呢?只需要在類加載器注冊的使用getConstructor(參數)方法。其中參數是我們構造器中的參數的類型。代碼如下:
1 public ReflectServiceImpl2 getInstance(){ 2 ReflectServiceImpl2 object=null; 3 try { 4 object=(ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2") 5 .getConstructor(String.class).newInstance("張三"); 6 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | InvocationTargetException |NoSuchMethodException e) { 7 e.printStackTrace(); 8 } 9 return object; 10 }
如4、5行所示:
先通過forName加載到類的加載器。然后通過getConstructor方法,它的參數可以是多個,這里定義String.class,意為有且只有一個參數類型為String 的構建方法。通過這個方法可以對重名方法進行排除,此時再用newInstance方法生成對象,只是newInstance方法也多了一個參數“張三”而已。實際上就等於object=new ReflectServiceImpl2("張三").只是利用了反射來生成對象而已。
1.3 反射方法
在使用反射方法之前需要先獲取對象,得到了方法才能夠去反射。
我們使用 ReflectServiceImpl 類為例。
ReflectServiceImpl 類代碼:
1 public class ReflectServiceImpl { 2 public void sayHello(String name){ 3 System.out.println("hello"+name); 4 } 5 }
調用方法:
1 public Object reflect(){ 2 ReflectServiceImpl object=null; 3 Object returnObj=null; 4 //反射生成對象 5 try { 6 object = (ReflectServiceImpl) Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance(); 7 //反射生成方法並調度 8 Method method = object.getClass().getMethod("sayHello", String.class); 9 returnObj= method.invoke(object, "張三"); 10 }catch( ClassNotFoundException| NoSuchMethodException| InvocationTargetException| IllegalAccessException| InstantiationException e ) { 11 e.printStackTrace(); 12 } 13 return returnObj; 14 }
當有具體對象 object(類型為ReflectServiceImpl),而不知道具體是哪個類的時候,也可以使用object.getClass().getMethod("sayHello", String.class);來替代它,其中第一個參數是方法的名稱,第二個參數是參數類型,是一個列表,多個參數可以繼續編寫多個類型,這樣便能夠獲得反射的方法對象。反射方法時運用 method.invoke(object, "張三");調用的,第一個參數為object,就是確定用哪個對象調用方法,而“張三”是參數,這就等同於object.sayHello("張三");若存在多個參數可以寫成Method.invoke(target,obj1,obj2.obj3...),這些要根據對象的具體方法來確定。
1.4 測試
以ReflectServiceImpl為例:
1 package com.lean.reflect; 2 import java.lang.reflect.InvocationTargetException; 3 import java.lang.reflect.Method; 4 public class ReflectServiceImpl { 5 //屬性 6 private String name; 7 //默認的構造方法 8 public ReflectServiceImpl() { 9 super(); 10 } 11 //帶參數的構造方法 12 public ReflectServiceImpl(String name) { 13 this.name=name; 14 } 15 //方法 sayHelo 16 public void sayHello(String name){ 17 System.out.println("hello "+name); 18 } 19 //調用方法 20 public Object reflect(){ 21 ReflectServiceImpl object=null; 22 Object returnObj=null; 23 //反射生成對象 24 try { 25 object = (ReflectServiceImpl) Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance(); 26 //反射生成方法並調度 27 Method method = object.getClass().getMethod("sayHello", String.class); 28 returnObj= method.invoke(object, "張三"); 29 }catch( ClassNotFoundException| NoSuchMethodException| InvocationTargetException| IllegalAccessException| InstantiationException e ) { 30 e.printStackTrace(); 31 } 32 return returnObj; 33 } 34 //獲取對象 35 public ReflectServiceImpl getInstance(){ 36 ReflectServiceImpl object=null; 37 try { 38 object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance(); 39 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 40 e.printStackTrace(); 41 } 42 return object; 43 } 44 //測試 45 public static void main(String[] args) { 46 ReflectServiceImpl rsl= new ReflectServiceImpl(); 47 rsl.reflect(); 48 } 49 }
效果圖: