java反射構建對象和方法的反射調用


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 }

效果圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM