Java基礎之 — 反射(非常重要)

課程地址:Java基礎之 — 反射(非常重要)

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

一、反射的概述

JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。

要想解剖一個類,必須先要獲取到該類的字節碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個字節碼文件對應的Class類型的對象.

以上的總結就是什么是反射

反射就是把java類中的各種成分映射成一個個的Java對象

例如:一個類有:成員變量、方法、構造方法、包等等信息,利用反射技術可以對一個類進行解剖,把個個組成部分映射成一個個對象。

 (其實:一個類中這些成員方法、構造方法、在加入類中都有一個類來描述)

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

熟悉一下加載的時候:Class對象的由來是將class文件讀入內存,并為之創建一個Class對象。

image

其中這個Class對象很特殊。我們先了解一下這個Class類

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

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

image

Class 類的實例表示正在運行的 Java 應用程序中的類和接口。也就是jvm中有N多的實例每個類都有該Class對象。(包括基本數據類型)

Class 沒有公共構造方法。Class 對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的defineClass 方法自動構造的。也就是這不需要我們自己去處理創建,JVM已經幫我們創建好了。

沒有公共的構造方法,方法共有64個太多了。下面用到哪個就詳解哪個吧

image

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

先寫一個Student類。

1、獲取Class對象的三種方式

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

其中1.1是因為Object類中的getClass方法、因為所有類都繼承Object類。從而調用Object類來獲取

image

[java] view plain copy

<embed id="ZeroClipboardMovie_1" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_1" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_20" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_20" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=20&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. <span style="font-size:18px;">package fanshe;

  2. /**

    • 獲取Class對象的三種方式
    • 1 Object ——> getClass();
    • 2 任何數據類型(包括基本數據類型)都有一個“靜態”的class屬性
    • 3 通過Class類的靜態方法:forName(String className)(常用)
  3. */

  4. public class Fanshe {

  5. public static void main(String[] args) {

  6. //第一種方式獲取Class對象

  7. Student stu1 = new Student();//這一new 產生一個Student對象,一個Class對象。

  8. Class stuClass = stu1.getClass();//獲取Class對象

  9. System.out.println(stuClass.getName());

  10. //第二種方式獲取Class對象

  11. Class stuClass2 = Student.class;

  12. System.out.println(stuClass == stuClass2);//判斷第一種方式獲取的Class對象和第二種方式獲取的是否是同一個

  13. //第三種方式獲取Class對象

  14. try {

  15. Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必須是真實路徑,就是帶包名的類路徑,包名.類名

  16. System.out.println(stuClass3 == stuClass2);//判斷三種方式是否獲取的是同一個Class對象

  17. } catch (ClassNotFoundException e) {

  18. e.printStackTrace();

  19. }

  20. }

  21. }</span>

注意:在運行期間,一個類,只有一個Class對象產生。

三種方式常用第三種,第一種對象都有了還要反射干什么。第二種需要導入類的包,依賴太強,不導包就拋編譯錯誤。一般都第三種,一個字符串可以傳入也可寫在配置文件中等多種方法。

2、通過反射獲取構造方法并使用:

student類:

[java] view plain copy

<embed id="ZeroClipboardMovie_2" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_2" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_21" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_21" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=21&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. package fanshe;

  2. public class Student {

  3. //---------------構造方法-------------------

  4. //(默認的構造方法)

  5. Student(String str){

  6. System.out.println("(默認)的構造方法 s = " + str);

  7. }

  8. //無參構造方法

  9. public Student(){

  10. System.out.println("調用了公有、無參構造方法執行了。。。");

  11. }

  12. //有一個參數的構造方法

  13. public Student(char name){

  14. System.out.println("姓名:" + name);

  15. }

  16. //有多個參數的構造方法

  17. public Student(String name ,int age){

  18. System.out.println("姓名:"+name+"年齡:"+ age);//這的執行效率有問題,以后解決。

  19. }

  20. //受保護的構造方法

  21. protected Student(boolean n){

  22. System.out.println("受保護的構造方法 n = " + n);

  23. }

  24. //私有構造方法

  25. private Student(int age){

  26. System.out.println("私有的構造方法 年齡:"+ age);

  27. }

  28. }

共有6個構造方法;

測試類:

[java] view plain copy

<embed id="ZeroClipboardMovie_3" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_3" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_22" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_22" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=22&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. package fanshe;

  2. import java.lang.reflect.Constructor;

  3. /*

    • 通過Class對象可以獲取某個類中的:構造方法、成員變量、成員方法;并訪問成員;
    • 1.獲取構造方法:
    •  1).批量的方法: 
      
    •      public Constructor[] getConstructors():所有"公有的"構造方法 
      
  4. public Constructor[] getDeclaredConstructors():獲取所有的構造方法(包括私有、受保護、默認、公有)

    •  2).獲取單個的方法,并調用: 
      
    •      public Constructor getConstructor(Class... parameterTypes):獲取單個的"公有的"構造方法: 
      
    •      public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個構造方法"可以是私有的,或受保護、默認、公有; 
      
    •      調用構造方法: 
      
    •      Constructor-->newInstance(Object... initargs) 
      
  5. */

  6. public class Constructors {

  7. public static void main(String[] args) throws Exception {

  8. //1.加載Class對象

  9. Class clazz = Class.forName("fanshe.Student");

  10. //2.獲取所有公有構造方法

  11. System.out.println("**********************所有公有構造方法*********************************");

  12. Constructor[] conArray = clazz.getConstructors();

  13. for(Constructor c : conArray){

  14. System.out.println(c);

  15. }

  16. System.out.println("************所有的構造方法(包括:私有、受保護、默認、公有)***************");

  17. conArray = clazz.getDeclaredConstructors();

  18. for(Constructor c : conArray){

  19. System.out.println(c);

  20. }

  21. System.out.println("*****************獲取公有、無參的構造方法*******************************");

  22. Constructor con = clazz.getConstructor(null);

  23. //1>、因為是無參的構造方法所以類型是一個null,不寫也可以:這里需要的是一個參數的類型,切記是類型

  24. //2>、返回的是描述這個無參構造函數的類對象。

  25. System.out.println("con = " + con);

  26. //調用構造方法

  27. Object obj = con.newInstance();

  28. // System.out.println("obj = " + obj);

  29. // Student stu = (Student)obj;

  30. System.out.println("******************獲取私有構造方法,并調用*******************************");

  31. con = clazz.getDeclaredConstructor(char.class);

  32. System.out.println(con);

  33. //調用構造方法

  34. con.setAccessible(true);//暴力訪問(忽略掉訪問修飾符)

  35. obj = con.newInstance('男');

  36. }

  37. }

后臺輸出:

[java] view plain copy

<embed id="ZeroClipboardMovie_4" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_4" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_23" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_23" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=23&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. **********************所有公有構造方法*********************************
  2. public fanshe.Student(java.lang.String,int)
  3. public fanshe.Student(char)
  4. public fanshe.Student()
  5. ************所有的構造方法(包括:私有、受保護、默認、公有)***************
  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. *****************獲取公有、無參的構造方法*******************************
  13. con = public fanshe.Student()
  14. 調用了公有、無參構造方法執行了。。。
  15. ******************獲取私有構造方法,并調用*******************************
  16. public fanshe.Student(char)
  17. 姓名:男

調用方法:

1.獲取構造方法:

1).批量的方法:
public Constructor[] getConstructors():所有"公有的"構造方法
public Constructor[] getDeclaredConstructors():獲取所有的構造方法(包括私有、受保護、默認、公有)

2).獲取單個的方法,并調用:
public Constructor getConstructor(Class... parameterTypes):獲取單個的"公有的"構造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個構造方法"可以是私有的,或受保護、默認、公有;

調用構造方法:

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

2、newInstance是 Constructor類的方法(管理構造函數的類)

api的解釋為:

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

它的返回值是T類型,所以newInstance是創建了一個構造方法的聲明類的新實例對象。并為之調用

3、獲取成員變量并調用

student類:

[java] view plain copy

<embed id="ZeroClipboardMovie_5" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_5" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_24" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_24" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=24&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. <span style="font-size:14px;">package fanshe.field;

  2. public class Student {

  3. public Student(){

  4. }

  5. //**********字段*************//

  6. public String name;

  7. protected int age;

  8. char sex;

  9. private String phoneNum;

  10. @Override

  11. public String toString() {

  12. return "Student [name=" + name + ", age=" + age + ", sex=" + sex

    • ", phoneNum=" + phoneNum + "]";
  13. }

  14. }</span>

測試類:

[java] view plain copy

<embed id="ZeroClipboardMovie_6" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_6" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_25" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_25" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=25&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. <span style="font-size:14px;">package fanshe.field;

  2. import java.lang.reflect.Field;

  3. /*

    • 獲取成員變量并調用:
    • 1.批量的
    •  1).Field[] getFields():獲取所有的"公有字段" 
      
    •  2).Field[] getDeclaredFields():獲取所有字段,包括:私有、受保護、默認、公有; 
      
    • 2.獲取單個的:
    •  1).public Field getField(String fieldName):獲取某個"公有的"字段; 
      
    •  2).public Field getDeclaredField(String fieldName):獲取某個字段(可以是私有的) 
      
    • 設置字段的值:
    •  Field --> public void set(Object obj,Object value): 
      
    •              參數說明: 
      
    •              1.obj:要設置的字段所在的對象; 
      
    •              2.value:要為字段設置的值; 
      
  4. */

  5. public class Fields {

  6. public static void main(String[] args) throws Exception {

  7. //1.獲取Class對象

  8. Class stuClass = Class.forName("fanshe.field.Student");

  9. //2.獲取字段

  10. System.out.println("************獲取所有公有的字段********************");

  11. Field[] fieldArray = stuClass.getFields();

  12. for(Field f : fieldArray){

  13. System.out.println(f);

  14. }

  15. System.out.println("************獲取所有的字段(包括私有、受保護、默認的)********************");

  16. fieldArray = stuClass.getDeclaredFields();

  17. for(Field f : fieldArray){

  18. System.out.println(f);

  19. }

  20. System.out.println("*************獲取公有字段**并調用***********************************");

  21. Field f = stuClass.getField("name");

  22. System.out.println(f);

  23. //獲取一個對象

  24. Object obj = stuClass.getConstructor().newInstance();//產生Student對象--》Student stu = new Student();

  25. //為字段設置值

  26. f.set(obj, "劉德華");//為Student對象中的name屬性賦值--》stu.name = "劉德華"

  27. //驗證

  28. Student stu = (Student)obj;

  29. System.out.println("驗證姓名:" + stu.name);

  30. System.out.println("**************獲取私有字段****并調用********************************");

  31. f = stuClass.getDeclaredField("phoneNum");

  32. System.out.println(f);

  33. f.setAccessible(true);//暴力反射,解除私有限定

  34. f.set(obj, "18888889999");

  35. System.out.println("驗證電話:" + stu);

  36. }

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

  38. </span>

后臺輸出:

[java] view plain copy

<embed id="ZeroClipboardMovie_7" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_7" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_26" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_26" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=26&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. ************獲取所有公有的字段********************
  2. public java.lang.String fanshe.field.Student.name
  3. ************獲取所有的字段(包括私有、受保護、默認的)********************
  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. *************獲取公有字段**并調用***********************************
  9. public java.lang.String fanshe.field.Student.name
  10. 驗證姓名:劉德華
  11. **************獲取私有字段****并調用********************************
  12. private java.lang.String fanshe.field.Student.phoneNum
  13. 驗證電話:Student [name=劉德華, age=0, sex=

由此可見

調用字段時:需要傳遞兩個參數:

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

第一個參數:要傳入設置的對象,第二個參數:要傳入實參

4、獲取成員方法并調用

student類:

[java] view plain copy

<embed id="ZeroClipboardMovie_8" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_8" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=8&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_27" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_27" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=27&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. <span style="font-size:14px;">package fanshe.method;

  2. public class Student {

  3. //**************成員方法***************//

  4. public void show1(String s){

  5. System.out.println("調用了:公有的,String參數的show1(): s = " + s);

  6. }

  7. protected void show2(){

  8. System.out.println("調用了:受保護的,無參的show2()");

  9. }

  10. void show3(){

  11. System.out.println("調用了:默認的,無參的show3()");

  12. }

  13. private String show4(int age){

  14. System.out.println("調用了,私有的,并且有返回值的,int參數的show4(): age = " + age);

  15. return "abcd";

  16. }

  17. }

  18. </span>

測試類:

[java] view plain copy

<embed id="ZeroClipboardMovie_9" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_9" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=9&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_28" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_28" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=28&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. <span style="font-size:14px;">package fanshe.method;

  2. import java.lang.reflect.Method;

  3. /*

    • 獲取成員方法并調用:
    • 1.批量的:
    •  public Method[] getMethods():獲取所有"公有方法";(包含了父類的方法也包含Object類) 
      
    •  public Method[] getDeclaredMethods():獲取所有的成員方法,包括私有的(不包括繼承的) 
      
    • 2.獲取單個的:
    •  public Method getMethod(String name,Class<?>... parameterTypes): 
      
    •              參數: 
      
    •                  name : 方法名; 
      
    •                  Class ... : 形參的Class類型對象 
      
    •  public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 
      
    • 調用方法:
    •  Method --> public Object invoke(Object obj,Object... args): 
      
    •              參數說明: 
      
    •              obj : 要調用方法的對象; 
      
    •              args:調用方式時所傳遞的實參; 
      
  4. ):

  5. */

  6. public class MethodClass {

  7. public static void main(String[] args) throws Exception {

  8. //1.獲取Class對象

  9. Class stuClass = Class.forName("fanshe.method.Student");

  10. //2.獲取所有公有方法

  11. System.out.println("***************獲取所有的”公有“方法*******************");

  12. stuClass.getMethods();

  13. Method[] methodArray = stuClass.getMethods();

  14. for(Method m : methodArray){

  15. System.out.println(m);

  16. }

  17. System.out.println("***************獲取所有的方法,包括私有的*******************");

  18. methodArray = stuClass.getDeclaredMethods();

  19. for(Method m : methodArray){

  20. System.out.println(m);

  21. }

  22. System.out.println("***************獲取公有的show1()方法*******************");

  23. Method m = stuClass.getMethod("show1", String.class);

  24. System.out.println(m);

  25. //實例化一個Student對象

  26. Object obj = stuClass.getConstructor().newInstance();

  27. m.invoke(obj, "劉德華");

  28. System.out.println("***************獲取私有的show4()方法******************");

  29. m = stuClass.getDeclaredMethod("show4", int.class);

  30. System.out.println(m);

  31. m.setAccessible(true);//解除私有限定

  32. Object result = m.invoke(obj, 20);//需要兩個參數,一個是要調用的對象(獲取有反射),一個是實參

  33. System.out.println("返回值:" + result);

  34. }

  35. }

  36. </span>

控制臺輸出:

[java] view plain copy

<embed id="ZeroClipboardMovie_10" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_10" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=10&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_29" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_29" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=29&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  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. 調用了:公有的,String參數的show1(): s = 劉德華
  20. ***************獲取私有的show4()方法******************
  21. private java.lang.String fanshe.method.Student.show4(int)
  22. 調用了,私有的,并且有返回值的,int參數的show4(): age = 20
  23. 返回值:abcd

由此可見:

m = stuClass.getDeclaredMethod("show4", int.class);//調用制定方法(所有包括私有的),需要傳入兩個參數,第一個是調用的方法名稱,第二個是方法的形參類型,切記是類型。 System.out.println(m);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj, 20);//需要兩個參數,一個是要調用的對象(獲取有反射),一個是實參
System.out.println("返回值:" + result);//

控制臺輸出:

[java] view plain copy

<embed id="ZeroClipboardMovie_11" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_11" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=11&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_30" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_30" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=30&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  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. 調用了:公有的,String參數的show1(): s = 劉德華
  20. ***************獲取私有的show4()方法******************
  21. private java.lang.String fanshe.method.Student.show4(int)
  22. 調用了,私有的,并且有返回值的,int參數的show4(): age = 20
  23. 返回值:abcd

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

5、反射main方法

student類:

[java] view plain copy

<embed id="ZeroClipboardMovie_12" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_12" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=12&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_31" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_31" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=31&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. <span style="font-size:14px;">package fanshe.main;

  2. public class Student {

  3. public static void main(String[] args) {

  4. System.out.println("main方法執行了。。。");

  5. }

  6. }

  7. </span>

測試類:

[java] view plain copy

<embed id="ZeroClipboardMovie_13" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_13" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=13&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_32" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_32" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=32&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. <span style="font-size:14px;">package fanshe.main;

  2. import java.lang.reflect.Method;

  3. /**

    • 獲取Student類的main方法、不要與當前的main方法搞混了
  4. */

  5. public class Main {

  6. public static void main(String[] args) {

  7. try {

  8. //1、獲取Student對象的字節碼

  9. Class clazz = Class.forName("fanshe.main.Student");

  10. //2、獲取main方法

  11. Method methodMain = clazz.getMethod("main", String[].class);//第一個參數:方法名稱,第二個參數:方法形參的類型,

  12. //3、調用main方法

  13. // methodMain.invoke(null, new String[]{"a","b","c"});

  14. //第一個參數,對象類型,因為方法是static靜態的,所以為null可以,第二個參數是String數組,這里要注意在jdk1.4時是數組,jdk1.5之后是可變參數

  15. //這里拆的時候將 new String[]{"a","b","c"} 拆成3個對象。。。所以需要將它強轉。

  16. methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一

  17. // methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二

  18. } catch (Exception e) {

  19. e.printStackTrace();

  20. }

  21. }

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

  23. </span>

控制臺輸出:

main方法執行了。。。

6、反射方法的其它使用之---通過反射運行配置文件內容

student類:

[java] view plain copy

<embed id="ZeroClipboardMovie_14" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_14" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=14&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_33" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_33" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=33&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

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

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

[java] view plain copy

<embed id="ZeroClipboardMovie_15" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_15" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=15&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_34" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_34" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=34&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

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

測試類:

[java] view plain copy

<embed id="ZeroClipboardMovie_16" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_16" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=16&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_35" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_35" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=35&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  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;

  6. /*

    • 我們利用反射和配置文件,可以使:應用程序更新時,對源碼無需進行任何修改
    • 我們只需要將新類發送給客戶端,并修改配置文件即可
  7. */

  8. public class Demo {

  9. public static void main(String[] args) throws Exception {

  10. //通過反射獲取Class對象

  11. Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"

  12. //2獲取show()方法

  13. Method m = stuClass.getMethod(getValue("methodName"));//show

  14. //3.調用show()方法

  15. m.invoke(stuClass.getConstructor().newInstance());

  16. }

  17. //此方法接收一個key,在配置文件中獲取相應的value

  18. public static String getValue(String key) throws IOException{

  19. Properties pro = new Properties();//獲取配置文件的對象

  20. FileReader in = new FileReader("pro.txt");//獲取輸入流

  21. pro.load(in);//將流加載到配置文件對象中

  22. in.close();

  23. return pro.getProperty(key);//返回根據key獲取的value值

  24. }

  25. }

控制臺輸出:

is show()

需求:
當我們升級這個系統時,不要Student類,而需要新寫一個Student2的類時,這時只需要更改pro.txt的文件內容就可以了。代碼就一點不用改動

要替換的student2類:

[java] view plain copy

<embed id="ZeroClipboardMovie_17" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_17" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=17&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_36" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_36" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=36&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

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

配置文件更改為:

[java] view plain copy

<embed id="ZeroClipboardMovie_18" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_18" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=18&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_37" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_37" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=37&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

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

控制臺輸出:

is show2();

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

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

測試類:

[java] view plain copy

<embed id="ZeroClipboardMovie_19" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_19" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=19&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

<embed id="ZeroClipboardMovie_38" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_38" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=38&width=16&height=16" wmode="transparent" width="16" height="16" align="middle">

  1. import java.lang.reflect.Method;

  2. import java.util.ArrayList;

  3. /*

    • 通過反射越過泛型檢查
    • 例如:有一個String泛型的集合,怎樣能向這個集合中添加一個Integer類型的值?
  4. */

  5. public class Demo {

  6. public static void main(String[] args) throws Exception{

  7. ArrayList<String> strList = new ArrayList<>();

  8. strList.add("aaa");

  9. strList.add("bbb");

  10. // strList.add(100);

  11. //獲取ArrayList的Class對象,反向的調用add()方法,添加數據

  12. Class listClass = strList.getClass(); //得到 strList 對象的字節碼 對象

  13. //獲取add()方法

  14. Method m = listClass.getMethod("add", Object.class);

  15. //調用add()方法

  16. m.invoke(strList, 100);

  17. //遍歷集合

  18. for(Object obj : strList){

  19. System.out.println(obj);

  20. }

  21. }

  22. }

控制臺輸出:

aaa
bbb
100

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容

  • 轉自https://blog.csdn.net/sinat_38259539/article/details/71...
    扎Zn了老Fe閱讀 490評論 0 4
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,707評論 18 399
  • (轉自csdn) 反射是框架設計的靈魂 (使用的前提條件:必須先得到代表的字節碼的Class,Class類用于表示...
    尼爾君閱讀 234評論 0 1
  • 姓名:邢喜全 公司:寧波大發化纖有限公司 組別:第235期 感謝一組 【日精進打卡第 73天】 【知~學習】 讀...
    天上人間_3c17閱讀 152評論 0 1
  • 感恩老師每天高能量的分享。以前光知道好的境遇去感恩,現在知道不如意的、不圓滿的也要去感恩,贊賞與感激這一切都是我創...
    間腦開發王宏彥閱讀 447評論 0 1