JAVA反射

轉(zhuǎn)自https://blog.csdn.net/sinat_38259539/article/details/71799078

反射是框架設(shè)計(jì)的靈魂

(使用的前提條件:必須先得到代表的字節(jié)碼的Class纪蜒,Class類用于表示.class文件(字節(jié)碼))

一狮含、反射的概述

JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類照棋,都能夠知道這個(gè)類的所有屬性和方法茂蚓;對(duì)于任意一個(gè)對(duì)象疏咐,都能夠調(diào)用它的任意一個(gè)方法和屬性禀挫;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制毕籽。

要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對(duì)象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個(gè)字節(jié)碼文件對(duì)應(yīng)的Class類型的對(duì)象.

以上的總結(jié)就是什么是反射

反射就是把java類中的各種成分映射成一個(gè)個(gè)的Java對(duì)象

例如:一個(gè)類有:成員變量井辆、方法关筒、構(gòu)造方法、包等等信息杯缺,利用反射技術(shù)可以對(duì)一個(gè)類進(jìn)行解剖蒸播,把個(gè)個(gè)組成部分映射成一個(gè)個(gè)對(duì)象。

 (其實(shí):一個(gè)類中這些成員方法萍肆、構(gòu)造方法袍榆、在加入類中都有一個(gè)類來描述)

如圖是類的正常加載過程:反射的原理在與class對(duì)象。

熟悉一下加載的時(shí)候:Class對(duì)象的由來是將class文件讀入內(nèi)存塘揣,并為之創(chuàng)建一個(gè)Class對(duì)象包雀。

image

其中這個(gè)Class對(duì)象很特殊。我們先了解一下這個(gè)Class類

二亲铡、查看Class類在java中的api詳解(1.7的API)

如何閱讀java中的api詳見java基礎(chǔ)之——String字符串處理

image

Class 類的實(shí)例表示正在運(yùn)行的 Java 應(yīng)用程序中的類和接口才写。也就是jvm中有N多的實(shí)例每個(gè)類都有該Class對(duì)象。(包括基本數(shù)據(jù)類型)

Class 沒有公共構(gòu)造方法奖蔓。Class 對(duì)象是在加載類時(shí)由 Java 虛擬機(jī)以及通過調(diào)用類加載器中的defineClass 方法自動(dòng)構(gòu)造的赞草。也就是這不需要我們自己去處理創(chuàng)建,JVM已經(jīng)幫我們創(chuàng)建好了吆鹤。

沒有公共的構(gòu)造方法房资,方法共有64個(gè)太多了。下面用到哪個(gè)就詳解哪個(gè)吧

image

三檀头、反射的使用(這里使用Student類做演示)

先寫一個(gè)Student類。

1岖沛、獲取Class對(duì)象的三種方式

1.1 Object ——> getClass(); 1.2 任何數(shù)據(jù)類型(包括基本數(shù)據(jù)類型)都有一個(gè)“靜態(tài)”的class屬性 1.3 通過Class類的靜態(tài)方法:forName(String className)(常用)

其中1.1是因?yàn)镺bject類中的getClass方法暑始、因?yàn)樗蓄惗祭^承Object類。從而調(diào)用Object類來獲取

image

獲取Class對(duì)象的三種方式
1 Object ——> getClass();
2 任何數(shù)據(jù)類型(包括基本數(shù)據(jù)類型)都有一個(gè)“靜態(tài)”的class屬性
3 通過Class類的靜態(tài)方法:forName(String className)(常用)

9.  public class Fanshe {  
10.  public static void main(String[] args) {  
11.  //第一種方式獲取Class對(duì)象    
12.  Student stu1 = new Student();//這一new 產(chǎn)生一個(gè)Student對(duì)象婴削,一個(gè)Class對(duì)象廊镜。  
13.  Class stuClass = stu1.getClass();//獲取Class對(duì)象  
14.  System.out.println(stuClass.getName());  

16.  //第二種方式獲取Class對(duì)象  
17.  Class stuClass2 = Student.class;  
18.  System.out.println(stuClass == stuClass2);//判斷第一種方式獲取的Class對(duì)象和第二種方式獲取的是否是同一個(gè)  

20.  //第三種方式獲取Class對(duì)象  
21.  try {  
22.  Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必須是真實(shí)路徑,就是帶包名的類路徑唉俗,包名.類名  
23.  System.out.println(stuClass3 == stuClass2);//判斷三種方式是否獲取的是同一個(gè)Class對(duì)象  
24.  } catch (ClassNotFoundException e) {  
25.  e.printStackTrace();  
26.  }  

28.  }  
29.  }</span>  

注意:在運(yùn)行期間嗤朴,一個(gè)類,只有一個(gè)Class對(duì)象產(chǎn)生虫溜。

三種方式常用第三種雹姊,第一種對(duì)象都有了還要反射干什么。第二種需要導(dǎo)入類的包衡楞,依賴太強(qiáng)吱雏,不導(dǎo)包就拋編譯錯(cuò)誤。一般都第三種,一個(gè)字符串可以傳入也可寫在配置文件中等多種方法歧杏。

2镰惦、通過反射獲取構(gòu)造方法并使用:

student類:

1.  package fanshe;  

3.  public class Student {  

5.  //---------------構(gòu)造方法-------------------  
6.  //(默認(rèn)的構(gòu)造方法)  
7.  Student(String str){  
8.  System.out.println("(默認(rèn))的構(gòu)造方法 s = " + str);  
9.  }  

11.  //無參構(gòu)造方法  
12.  public Student(){  
13.  System.out.println("調(diào)用了公有、無參構(gòu)造方法執(zhí)行了犬绒。旺入。。");  
14.  }  

16.  //有一個(gè)參數(shù)的構(gòu)造方法  
17.  public Student(char name){  
18.  System.out.println("姓名:" + name);  
19.  }  

21.  //有多個(gè)參數(shù)的構(gòu)造方法  
22.  public Student(String name ,int age){  
23.  System.out.println("姓名:"+name+"年齡:"+ age);//這的執(zhí)行效率有問題凯力,以后解決茵瘾。  
24.  }  

26.  //受保護(hù)的構(gòu)造方法  
27.  protected Student(boolean n){  
28.  System.out.println("受保護(hù)的構(gòu)造方法 n = " + n);  
29.  }  

31.  //私有構(gòu)造方法  
32.  private Student(int age){  
33.  System.out.println("私有的構(gòu)造方法   年齡:"+ age);  
34.  }  

36.  }  

共有6個(gè)構(gòu)造方法;

測(cè)試類:

1.  package fanshe;  

3.  import java.lang.reflect.Constructor;  

6.  /* 
7.  * 通過Class對(duì)象可以獲取某個(gè)類中的:構(gòu)造方法沮协、成員變量龄捡、成員方法;并訪問成員慷暂; 
8.  *  
9.  * 1.獲取構(gòu)造方法: 
10.  *      1).批量的方法: 
11.  *          public Constructor[] getConstructors():所有"公有的"構(gòu)造方法 
12.  public Constructor[] getDeclaredConstructors():獲取所有的構(gòu)造方法(包括私有聘殖、受保護(hù)、默認(rèn)行瑞、公有) 

14.  *      2).獲取單個(gè)的方法奸腺,并調(diào)用: 
15.  *          public Constructor getConstructor(Class... parameterTypes):獲取單個(gè)的"公有的"構(gòu)造方法: 
16.  *          public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個(gè)構(gòu)造方法"可以是私有的,或受保護(hù)血久、默認(rèn)突照、公有; 
17.  *       
18.  *          調(diào)用構(gòu)造方法: 
19.  *          Constructor-->newInstance(Object... initargs) 
20.  */  
21.  public class Constructors {  

23.  public static void main(String[] args) throws Exception {  
24.  //1.加載Class對(duì)象  
25.  Class clazz = Class.forName("fanshe.Student");  

28.  //2.獲取所有公有構(gòu)造方法  
29.  System.out.println("**********************所有公有構(gòu)造方法*********************************");  
30.  Constructor[] conArray = clazz.getConstructors();  
31.  for(Constructor c : conArray){  
32.  System.out.println(c);  
33.  }  

36.  System.out.println("************所有的構(gòu)造方法(包括:私有氧吐、受保護(hù)讹蘑、默認(rèn)、公有)***************");  
37.  conArray = clazz.getDeclaredConstructors();  
38.  for(Constructor c : conArray){  
39.  System.out.println(c);  
40.  }  

42.  System.out.println("*****************獲取公有筑舅、無參的構(gòu)造方法*******************************");  
43.  Constructor con = clazz.getConstructor(null);  
44.  //1>座慰、因?yàn)槭菬o參的構(gòu)造方法所以類型是一個(gè)null,不寫也可以:這里需要的是一個(gè)參數(shù)的類型,切記是類型  
45.  //2>翠拣、返回的是描述這個(gè)無參構(gòu)造函數(shù)的類對(duì)象版仔。  

47.  System.out.println("con = " + con);  
48.  //調(diào)用構(gòu)造方法  
49.  Object obj = con.newInstance();  
50.  //  System.out.println("obj = " + obj);  
51.  //  Student stu = (Student)obj;  

53.  System.out.println("******************獲取私有構(gòu)造方法,并調(diào)用*******************************");  
54.  con = clazz.getDeclaredConstructor(char.class);  
55.  System.out.println(con);  
56.  //調(diào)用構(gòu)造方法  
57.  con.setAccessible(true);//暴力訪問(忽略掉訪問修飾符)  
58.  obj = con.newInstance('男');  
59.  }  

61.  }  

后臺(tái)輸出:

  1. **********************所有公有構(gòu)造方法*********************************
  2. public fanshe.Student(java.lang.String,int)
  3. public fanshe.Student(char)
  4. public fanshe.Student()
  5. ************所有的構(gòu)造方法(包括:私有误墓、受保護(hù)蛮粮、默認(rèn)、公有)***************
  6. private fanshe.Student(int)
  7. protected fanshe.Student(boolean)
  8. public fanshe.Student(java.lang.String,int)
  9. public fanshe.Student(char)
  10. public fanshe.Student()
  11. fanshe.Student(java.lang.String)
  12. *****************獲取公有谜慌、無參的構(gòu)造方法*******************************
  13. con = public fanshe.Student()
  14. 調(diào)用了公有然想、無參構(gòu)造方法執(zhí)行了。畦娄。又沾。
  15. ******************獲取私有構(gòu)造方法弊仪,并調(diào)用*******************************
  16. public fanshe.Student(char)
  17. 姓名:男

調(diào)用方法:

1.獲取構(gòu)造方法:

1).批量的方法:
public Constructor[] getConstructors():所有"公有的"構(gòu)造方法
public Constructor[] getDeclaredConstructors():獲取所有的構(gòu)造方法(包括私有、受保護(hù)杖刷、默認(rèn)励饵、公有)

2).獲取單個(gè)的方法,并調(diào)用:
public Constructor getConstructor(Class... parameterTypes):獲取單個(gè)的"公有的"構(gòu)造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個(gè)構(gòu)造方法"可以是私有的滑燃,或受保護(hù)役听、默認(rèn)、公有表窘;

調(diào)用構(gòu)造方法:

Constructor-->newInstance(Object... initargs)

2典予、newInstance是 Constructor類的方法(管理構(gòu)造函數(shù)的類)

api的解釋為:

**[](https://blog.csdn.net/sinat_38259539/article/details/71799078)**newInstance(Object... initargs)
使用此 Constructor 對(duì)象表示的構(gòu)造方法來創(chuàng)建該構(gòu)造方法的聲明類的新實(shí)例,并用指定的初始化參數(shù)初始化該實(shí)例乐严。

它的返回值是T類型瘤袖,所以newInstance是創(chuàng)建了一個(gè)構(gòu)造方法的聲明類的新實(shí)例對(duì)象。并為之調(diào)用

3昂验、獲取成員變量并調(diào)用

student類:

package fanshe.field;  

3.  public class Student {  
4.  public Student(){  

6.  }  
7.  //**********字段*************//  
8.  public String name;  
9.  protected int age;  
10.  char sex;  
11.  private String phoneNum;  

13.  @Override  
14.  public String toString() {  
15.  return "Student [name=" + name + ", age=" + age + ", sex=" + sex  
16.  + ", phoneNum=" + phoneNum + "]";  
17.  }  

20.  }</span>  

測(cè)試類:

 package fanshe.field;  
2.  import java.lang.reflect.Field;  
3.  /* 
4.  * 獲取成員變量并調(diào)用: 
5.  *  
6.  * 1.批量的 
7.  *      1).Field[] getFields():獲取所有的"公有字段" 
8.  *      2).Field[] getDeclaredFields():獲取所有字段捂敌,包括:私有、受保護(hù)既琴、默認(rèn)占婉、公有; 
9.  * 2.獲取單個(gè)的: 
10.  *      1).public Field getField(String fieldName):獲取某個(gè)"公有的"字段甫恩; 
11.  *      2).public Field getDeclaredField(String fieldName):獲取某個(gè)字段(可以是私有的) 
12.  *  
13.  *   設(shè)置字段的值: 
14.  *      Field --> public void set(Object obj,Object value): 
15.  *                  參數(shù)說明: 
16.  *                  1.obj:要設(shè)置的字段所在的對(duì)象逆济; 
17.  *                  2.value:要為字段設(shè)置的值; 
18.  *  
19.  */  
20.  public class Fields {  

22.  public static void main(String[] args) throws Exception {  
23.  //1.獲取Class對(duì)象  
24.  Class stuClass = Class.forName("fanshe.field.Student");  
25.  //2.獲取字段  
26.  System.out.println("************獲取所有公有的字段********************");  
27.  Field[] fieldArray = stuClass.getFields();  
28.  for(Field f : fieldArray){  
29.  System.out.println(f);  
30.  }  
31.  System.out.println("************獲取所有的字段(包括私有磺箕、受保護(hù)奖慌、默認(rèn)的)********************");  
32.  fieldArray = stuClass.getDeclaredFields();  
33.  for(Field f : fieldArray){  
34.  System.out.println(f);  
35.  }  
36.  System.out.println("*************獲取公有字段**并調(diào)用***********************************");  
37.  Field f = stuClass.getField("name");  
38.  System.out.println(f);  
39.  //獲取一個(gè)對(duì)象  
40.  Object obj = stuClass.getConstructor().newInstance();//產(chǎn)生Student對(duì)象--》Student stu = new Student();  
41.  //為字段設(shè)置值  
42.  f.set(obj, "劉德華");//為Student對(duì)象中的name屬性賦值--》stu.name = "劉德華"  
43.  //驗(yàn)證  
44.  Student stu = (Student)obj;  
45.  System.out.println("驗(yàn)證姓名:" + stu.name);  

48.  System.out.println("**************獲取私有字段****并調(diào)用********************************");  
49.  f = stuClass.getDeclaredField("phoneNum");  
50.  System.out.println(f);  
51.  f.setAccessible(true);//暴力反射,解除私有限定  
52.  f.set(obj, "18888889999");  
53.  System.out.println("驗(yàn)證電話:" + stu);  

55.  }  
56.  }</span><span style="font-size:18px;">  
57.  </span>  

后臺(tái)輸出:

  1. ************獲取所有公有的字段********************
  2. public java.lang.String fanshe.field.Student.name
  3. ************獲取所有的字段(包括私有松靡、受保護(hù)升薯、默認(rèn)的)********************
  4. public java.lang.String fanshe.field.Student.name
  5. protected int fanshe.field.Student.age
  6. char fanshe.field.Student.sex
  7. private java.lang.String fanshe.field.Student.phoneNum
  8. *************獲取公有字段**并調(diào)用***********************************
  9. public java.lang.String fanshe.field.Student.name
  10. 驗(yàn)證姓名:劉德華
  11. **************獲取私有字段****并調(diào)用********************************
  12. private java.lang.String fanshe.field.Student.phoneNum
  13. 驗(yàn)證電話:Student [name=劉德華, age=0, sex=

由此可見

調(diào)用字段時(shí):需要傳遞兩個(gè)參數(shù):

Object obj = stuClass.getConstructor().newInstance();//產(chǎn)生Student對(duì)象--》Student stu = new Student();
//為字段設(shè)置值
f.set(obj, "劉德華");//為Student對(duì)象中的name屬性賦值--》stu.name = "劉德華"

第一個(gè)參數(shù):要傳入設(shè)置的對(duì)象,第二個(gè)參數(shù):要傳入實(shí)參

4击困、獲取成員方法并調(diào)用

student類:

package fanshe.method;  

3.  public class Student {  
4.  //**************成員方法***************//  
5.  public void show1(String s){  
6.  System.out.println("調(diào)用了:公有的,String參數(shù)的show1(): s = " + s);  
7.  }  
8.  protected void show2(){  
9.  System.out.println("調(diào)用了:受保護(hù)的广凸,無參的show2()");  
10.  }  
11.  void show3(){  
12.  System.out.println("調(diào)用了:默認(rèn)的阅茶,無參的show3()");  
13.  }  
14.  private String show4(int age){  
15.  System.out.println("調(diào)用了,私有的谅海,并且有返回值的脸哀,int參數(shù)的show4(): age = " + age);  
16.  return "abcd";  
17.  }  
18.  }  
19.  </span>  

測(cè)試類:

package fanshe.method;  

3.  import java.lang.reflect.Method;  

5.  /* 
6.  * 獲取成員方法并調(diào)用: 
7.  *  
8.  * 1.批量的: 
9.  *      public Method[] getMethods():獲取所有"公有方法";(包含了父類的方法也包含Object類) 
10.  *      public Method[] getDeclaredMethods():獲取所有的成員方法扭吁,包括私有的(不包括繼承的) 
11.  * 2.獲取單個(gè)的: 
12.  *      public Method getMethod(String name,Class<?>... parameterTypes): 
13.  *                  參數(shù): 
14.  *                      name : 方法名撞蜂; 
15.  *                      Class ... : 形參的Class類型對(duì)象 
16.  *      public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 
17.  *  
18.  *   調(diào)用方法: 
19.  *      Method --> public Object invoke(Object obj,Object... args): 
20.  *                  參數(shù)說明: 
21.  *                  obj : 要調(diào)用方法的對(duì)象盲镶; 
22.  *                  args:調(diào)用方式時(shí)所傳遞的實(shí)參; 

24.  ): 
25.  */  
26.  public class MethodClass {  

28.  public static void main(String[] args) throws Exception {  
29.  //1.獲取Class對(duì)象  
30.  Class stuClass = Class.forName("fanshe.method.Student");  
31.  //2.獲取所有公有方法  
32.  System.out.println("***************獲取所有的”公有“方法*******************");  
33.  stuClass.getMethods();  
34.  Method[] methodArray = stuClass.getMethods();  
35.  for(Method m : methodArray){  
36.  System.out.println(m);  
37.  }  
38.  System.out.println("***************獲取所有的方法蝌诡,包括私有的*******************");  
39.  methodArray = stuClass.getDeclaredMethods();  
40.  for(Method m : methodArray){  
41.  System.out.println(m);  
42.  }  
43.  System.out.println("***************獲取公有的show1()方法*******************");  
44.  Method m = stuClass.getMethod("show1", String.class);  
45.  System.out.println(m);  
46.  //實(shí)例化一個(gè)Student對(duì)象  
47.  Object obj = stuClass.getConstructor().newInstance();  
48.  m.invoke(obj, "劉德華");  

50.  System.out.println("***************獲取私有的show4()方法******************");  
51.  m = stuClass.getDeclaredMethod("show4", int.class);  
52.  System.out.println(m);  
53.  m.setAccessible(true);//解除私有限定  
54.  Object result = m.invoke(obj, 20);//需要兩個(gè)參數(shù)溉贿,一個(gè)是要調(diào)用的對(duì)象(獲取有反射),一個(gè)是實(shí)參  
55.  System.out.println("返回值:" + result);  

58.  }  
59.  }  
60.  </span>  

控制臺(tái)輸出:

  1. ***************獲取所有的”公有“方法*******************
  2. public void fanshe.method.Student.show1(java.lang.String)
  3. public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
  4. public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
  5. public final void java.lang.Object.wait() throws java.lang.InterruptedException
  6. public boolean java.lang.Object.equals(java.lang.Object)
  7. public java.lang.String java.lang.Object.toString()
  8. public native int java.lang.Object.hashCode()
  9. public final native java.lang.Class java.lang.Object.getClass()
  10. public final native void java.lang.Object.notify()
  11. public final native void java.lang.Object.notifyAll()
  12. ***************獲取所有的方法浦旱,包括私有的*******************
  13. public void fanshe.method.Student.show1(java.lang.String)
  14. private java.lang.String fanshe.method.Student.show4(int)
  15. protected void fanshe.method.Student.show2()
  16. void fanshe.method.Student.show3()
  17. ***************獲取公有的show1()方法*******************
  18. public void fanshe.method.Student.show1(java.lang.String)
  19. 調(diào)用了:公有的宇色,String參數(shù)的show1(): s = 劉德華
  20. ***************獲取私有的show4()方法******************
  21. private java.lang.String fanshe.method.Student.show4(int)
  22. 調(diào)用了,私有的颁湖,并且有返回值的宣蠕,int參數(shù)的show4(): age = 20
  23. 返回值:abcd

由此可見:

m = stuClass.getDeclaredMethod("show4", int.class);//調(diào)用制定方法(所有包括私有的),需要傳入兩個(gè)參數(shù)甥捺,第一個(gè)是調(diào)用的方法名稱抢蚀,第二個(gè)是方法的形參類型,切記是類型镰禾。 System.out.println(m);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj, 20);//需要兩個(gè)參數(shù)皿曲,一個(gè)是要調(diào)用的對(duì)象(獲取有反射),一個(gè)是實(shí)參
System.out.println("返回值:" + result);//

控制臺(tái)輸出:

  1. ***************獲取所有的”公有“方法*******************
  2. public void fanshe.method.Student.show1(java.lang.String)
  3. public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
  4. public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
  5. public final void java.lang.Object.wait() throws java.lang.InterruptedException
  6. public boolean java.lang.Object.equals(java.lang.Object)
  7. public java.lang.String java.lang.Object.toString()
  8. public native int java.lang.Object.hashCode()
  9. public final native java.lang.Class java.lang.Object.getClass()
  10. public final native void java.lang.Object.notify()
  11. public final native void java.lang.Object.notifyAll()
  12. ***************獲取所有的方法羡微,包括私有的*******************
  13. public void fanshe.method.Student.show1(java.lang.String)
  14. private java.lang.String fanshe.method.Student.show4(int)
  15. protected void fanshe.method.Student.show2()
  16. void fanshe.method.Student.show3()
  17. ***************獲取公有的show1()方法*******************
  18. public void fanshe.method.Student.show1(java.lang.String)
  19. 調(diào)用了:公有的谷饿,String參數(shù)的show1(): s = 劉德華
  20. ***************獲取私有的show4()方法******************
  21. private java.lang.String fanshe.method.Student.show4(int)
  22. 調(diào)用了,私有的妈倔,并且有返回值的博投,int參數(shù)的show4(): age = 20
  23. 返回值:abcd

其實(shí)這里的成員方法:在模型中有屬性一詞,就是那些setter()方法和getter()方法盯蝴。還有字段組成毅哗,這些內(nèi)容在內(nèi)省中詳解

5、反射main方法

student類:

package fanshe.main;  

3.  public class Student {  

5.  public static void main(String[] args) {  
6.  System.out.println("main方法執(zhí)行了捧挺。虑绵。。");  
7.  }  
8.  }  
9.  </span>  

測(cè)試類:

package fanshe.main;  

3.  import java.lang.reflect.Method;  

5.  /** 
6.  * 獲取Student類的main方法闽烙、不要與當(dāng)前的main方法搞混了 
7.  */  
8.  public class Main {  

10.  public static void main(String[] args) {  
11.  try {  
12.  //1翅睛、獲取Student對(duì)象的字節(jié)碼  
13.  Class clazz = Class.forName("fanshe.main.Student");  

15.  //2、獲取main方法  
16.  Method methodMain = clazz.getMethod("main", String[].class);//第一個(gè)參數(shù):方法名稱黑竞,第二個(gè)參數(shù):方法形參的類型捕发,  
17.  //3、調(diào)用main方法  
18.  // methodMain.invoke(null, new String[]{"a","b","c"});  
19.  //第一個(gè)參數(shù)很魂,對(duì)象類型扎酷,因?yàn)榉椒ㄊ莝tatic靜態(tài)的,所以為null可以遏匆,第二個(gè)參數(shù)是String數(shù)組法挨,這里要注意在jdk1.4時(shí)是數(shù)組谁榜,jdk1.5之后是可變參數(shù)  
20.  //這里拆的時(shí)候?qū)? new String[]{"a","b","c"} 拆成3個(gè)對(duì)象。凡纳。窃植。所以需要將它強(qiáng)轉(zhuǎn)。  
21.  methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一  
22.  // methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二  

24.  } catch (Exception e) {  
25.  e.printStackTrace();  
26.  }  

29.  }  
30.  }</span><span style="font-size:18px;">  
31.  </span>  

控制臺(tái)輸出:

main方法執(zhí)行了惫企。撕瞧。。

6狞尔、反射方法的其它使用之---通過反射運(yùn)行配置文件內(nèi)容

student類:

1.  public class Student {  
2.  public void show(){  
3.  System.out.println("is show()");  
4.  }  
5.  }  

配置文件以txt文件為例子(pro.txt):

1.  className = cn.fanshe.Student  
2.  methodName = show  

測(cè)試類:

1.  import java.io.FileNotFoundException;  
2.  import java.io.FileReader;  
3.  import java.io.IOException;  
4.  import java.lang.reflect.Method;  
5.  import java.util.Properties;  

7.  /* 
8.  * 我們利用反射和配置文件丛版,可以使:應(yīng)用程序更新時(shí),對(duì)源碼無需進(jìn)行任何修改 
9.  * 我們只需要將新類發(fā)送給客戶端偏序,并修改配置文件即可 
10.  */  
11.  public class Demo {  
12.  public static void main(String[] args) throws Exception {  
13.  //通過反射獲取Class對(duì)象  
14.  Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"  
15.  //2獲取show()方法  
16.  Method m = stuClass.getMethod(getValue("methodName"));//show  
17.  //3.調(diào)用show()方法  
18.  m.invoke(stuClass.getConstructor().newInstance());  

20.  }  

22.  //此方法接收一個(gè)key页畦,在配置文件中獲取相應(yīng)的value  
23.  public static String getValue(String key) throws IOException{  
24.  Properties pro = new Properties();//獲取配置文件的對(duì)象  
25.  FileReader in = new FileReader("pro.txt");//獲取輸入流  
26.  pro.load(in);//將流加載到配置文件對(duì)象中  
27.  in.close();  
28.  return pro.getProperty(key);//返回根據(jù)key獲取的value值  
29.  }  
30.  }  

控制臺(tái)輸出:

is show()

需求:
當(dāng)我們升級(jí)這個(gè)系統(tǒng)時(shí),不要Student類研儒,而需要新寫一個(gè)Student2的類時(shí)豫缨,這時(shí)只需要更改pro.txt的文件內(nèi)容就可以了。代碼就一點(diǎn)不用改動(dòng)

要替換的student2類:

1.  className = cn.fanshe.Student2  
2.  methodName = show2  

控制臺(tái)輸出:

is show2();

7端朵、反射方法的其它使用之---通過反射越過泛型檢查

泛型用在編譯期好芭,編譯過后泛型擦除(消失掉)。所以是可以通過反射越過泛型檢查的

測(cè)試類:

1.  import java.lang.reflect.Method;  
2.  import java.util.ArrayList;  

4.  /* 
5.  * 通過反射越過泛型檢查 
6.  *  
7.  * 例如:有一個(gè)String泛型的集合冲呢,怎樣能向這個(gè)集合中添加一個(gè)Integer類型的值舍败? 
8.  */  
9.  public class Demo {  
10.  public static void main(String[] args) throws Exception{  
11.  ArrayList<String> strList = new ArrayList<>();  
12.  strList.add("aaa");  
13.  strList.add("bbb");  

15.  //  strList.add(100);  
16.  //獲取ArrayList的Class對(duì)象,反向的調(diào)用add()方法敬拓,添加數(shù)據(jù)  
17.  Class listClass = strList.getClass(); //得到 strList 對(duì)象的字節(jié)碼 對(duì)象  
18.  //獲取add()方法  
19.  Method m = listClass.getMethod("add", Object.class);  
20.  //調(diào)用add()方法  
21.  m.invoke(strList, 100);  

23.  //遍歷集合  
24.  for(Object obj : strList){  
25.  System.out.println(obj);  
26.  }  
27.  }  
28.  }  

控制臺(tái)輸出:

aaa
bbb
100 

//反射就總結(jié)到這邻薯,下面的內(nèi)省章節(jié)也和反射有關(guān),可以算是反射的高級(jí)使用吧乘凸,如果有興趣厕诡,可以繼續(xù)查看總結(jié)的內(nèi)省部分。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末营勤,一起剝皮案震驚了整個(gè)濱河市灵嫌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌葛作,老刑警劉巖醒第,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異进鸠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)形病,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門客年,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霞幅,“玉大人,你說我怎么就攤上這事量瓜∷究遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵绍傲,是天一觀的道長(zhǎng)扔傅。 經(jīng)常有香客問我,道長(zhǎng)烫饼,這世上最難降的妖魔是什么猎塞? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮杠纵,結(jié)果婚禮上荠耽,老公的妹妹穿的比我還像新娘。我一直安慰自己比藻,他們只是感情好铝量,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著银亲,像睡著了一般慢叨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上务蝠,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天拍谐,我揣著相機(jī)與錄音,去河邊找鬼请梢。 笑死赠尾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的毅弧。 我是一名探鬼主播气嫁,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼够坐!你這毒婦竟也來了寸宵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤元咙,失蹤者是張志新(化名)和其女友劉穎梯影,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庶香,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甲棍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赶掖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片感猛。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡七扰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陪白,到底是詐尸還是另有隱情颈走,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布咱士,位于F島的核電站立由,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏序厉。R本人自食惡果不足惜锐膜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脂矫。 院中可真熱鬧枣耀,春花似錦、人聲如沸庭再。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拄轻。三九已至颅围,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恨搓,已是汗流浹背院促。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斧抱,地道東北人常拓。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像辉浦,于是被迫代替她去往敵國(guó)和親弄抬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 什么是java反射: JAVA反射機(jī)制是在運(yùn)行狀態(tài)中宪郊,對(duì)于任意一個(gè)類掂恕,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一...
    樂百事52淑熙閱讀 333評(píng)論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法弛槐,類相關(guān)的語法懊亡,內(nèi)部類的語法,繼承相關(guān)的語法乎串,異常的語法店枣,線程的語...
    子非魚_t_閱讀 31,582評(píng)論 18 399
  • 1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以讓我們?cè)谶\(yùn)行時(shí)獲取類的函數(shù)、...
    Ten_Minutes閱讀 530評(píng)論 0 4
  • 時(shí)光坏瞄,留不住昨天; 緣分,停不在初見甩卓。 感情,需要的是理解;相處蕉斜, 需要的是默契;陪伴逾柿,需要的是耐心。 人生能相遇...
    樂鈫閱讀 355評(píng)論 0 0
  • 1.設(shè)置文章超出n行顯示省略號(hào) overflow:hidden; text-overflow:ellipsis; ...
    木景蔓閱讀 81評(píng)論 1 1