日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
詳解Java反射機制實例

在 Java 運行時環(huán)境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意

精河ssl適用于網站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

一個對象,能否調用它的任意一個方法?答案是肯定的。這種動態(tài)獲取類的信息,以及動態(tài)

調用對象的方法的功能來自于Java 語言的反射(Reflection)機制。Java 反射機制主要提供

了以下功能:

在運行時判斷任意一個對象所屬的類;

在運行時構造任意一個類的對象;

在運行時判斷任意一個類所具有的成員變量和方法;

在運行時調用任意一個對象的方法;

生成動態(tài)代理。

在 JDK 中,主要由以下類來實現(xiàn)Java 反射機制,這些類都位于java.lang.reflect

包中。

Class類:代表一個類。

Field類:代表類的成員變量(成員變量也稱為類的屬性)。

Method類:代表類的方法。

Constructor 類:代表類的構造方法。

Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組元素的靜態(tài)方法。

如例程1所示DumpMethods 類演示了Reflection API的基本作用,它讀取命令

行參數(shù)指定的類名,然后打印這個類所具有的方法信息:

例程1:DumpMethods.java

Java代碼

 
 
 
  1. import java.lang.reflect.*;     
  2.     
  3. public class DumpMethods {     
  4.     public static void main(String args[]) throws Exception {     
  5.         // 加載并初始化命令行參數(shù)指定的類     
  6.         Class classType = Class.forName(args[0]);     
  7.         // 獲得類的所有方法     
  8.         Method methods[] = classType.getDeclaredMethods();     
  9.         for (int i = 0; i < methods.length; i++)     
  10.             System.out.println(methods[i].toString());     
  11.     }     
  12. }    

運行命令“java DumpMethods java.util.Stack”,就會顯示java.util.Stack類所具有的方法,程序的打印結果如下:

 
 
 
  1. public synchronized java.lang.Object java.util.Stack.pop()  
  2.  
  3. public java.lang.Object java.util.Stack.push(java.lang.Object)  
  4.  
  5. public boolean java.util.Stack.empty()  
  6.  
  7. public synchronized java.lang.Object java.util.Stack.peek()  
  8.  
  9. public synchronized int java.util.Stack.search(java.lang.Object)  

如例程2 所示ReflectTester 類進一步演示了Reflection API 的基本使用方法。

ReflectTester 類有一個copy(Object object)方法,這個方法能夠創(chuàng)建一個和參數(shù)object同樣類型的對象,然后把object對象中的所有屬性復制到新建的對象中,并將它返回。這個例子只能復制簡單的JavaBean,假定JavaBean的每個屬性都有public類型的

getXXX()和setXXX()方法。

例程2 ReflectTester.java

Java代碼

 
 
 
  1. import java.lang.reflect.*;     
  2.     
  3. public class ReflectTester {     
  4.     public Object copy(Object object) throws Exception {     
  5.         // 獲得對象的類型     
  6.         Class classType = object.getClass();     
  7.         System.out.println("Class:" + classType.getName());     
  8.         // 通過默認構造方法創(chuàng)建一個新的對象     
  9.         Object objectCopy = classType.getConstructor(new Class[] {})     
  10.                 .newInstance(new Object[] {});     
  11.         // 獲得對象的所有屬性     
  12.         Field fields[] = classType.getDeclaredFields();     
  13.         for (int i = 0; i < fields.length; i++) {     
  14.             Field field = fields[i];     
  15.             String fieldName = field.getName();     
  16.             String firstLetter = fieldName.substring(0, 1).toUpperCase();     
  17.             // 獲得和屬性對應的getXXX()方法的名字     
  18.             String getMethodName = "get" + firstLetter + fieldName.substring(1);     
  19.             // 獲得和屬性對應的setXXX()方法的名字     
  20.             String setMethodName = "set" + firstLetter + fieldName.substring(1);     
  21.             // 獲得和屬性對應的getXXX()方法     
  22.             Method getMethod = classType.getMethod(getMethodName,     
  23.                     new Class[] {});     
  24.             // 獲得和屬性對應的setXXX()方法     
  25.             Method setMethod = classType.getMethod(setMethodName,     
  26.                     new Class[] { field.getType() });     
  27.             // 調用原對象的getXXX()方法     
  28.             Object value = getMethod.invoke(object, new Object[] {});     
  29.             System.out.println(fieldName + ":" + value);     
  30.             // 調用復制對象的setXXX()方法     
  31.             setMethod.invoke(objectCopy, new Object[] { value });     
  32.         }     
  33.         return objectCopy;     
  34.     }     
  35.     
  36.     public static void main(String[] args) throws Exception {     
  37.         Customer customer = new Customer("Tom", 21);     
  38.         customer.setId(new Long(1));     
  39.         Customer customerCopy = (Customer) new ReflectTester().copy(customer);     
  40.         System.out.println("Copy information:" + customerCopy.getName() + " "    
  41.                 + customerCopy.getAge());     
  42.     }     
  43. }     
  44.     
  45. class Customer { // Customer類是一個JavaBean     
  46.     private Long id;     
  47.     private String name;     
  48.     private int age;     
  49.     
  50.     public Customer() {     
  51.     }     
  52.     
  53.     public Customer(String name, int age) {     
  54.         this.name = name;     
  55.         this.age = age;     
  56.     }     
  57.     
  58.     public Long getId() {     
  59.         return id;     
  60.     }     
  61.     
  62.     public void setId(Long id) {     
  63.         this.id = id;     
  64.     }     
  65.     
  66.     public String getName() {     
  67.         return name;     
  68.     }     
  69.     
  70.     public void setName(String name) {     
  71.         this.name = name;     
  72.     }     
  73.     
  74.     public int getAge() {     
  75.         return age;     
  76.     }     
  77.     
  78.     public void setAge(int age) {     
  79.         this.age = age;     
  80.     }     
  81. }   

執(zhí)行結果:Class:Customer

id:1

name:Tom

age:21

Copy information:Tom 21

Class類是Reflection API中的核心類,它有以下方法。

getName():獲得類的完整名字。

getFields():獲得類的public類型的屬性。

getDeclaredFields():獲得類的所有屬性。

getMethods():獲得類的public類型的方法。

getDeclaredMethods():獲得類的所有方法。

getMethod(String name, Class[] parameterTypes):獲得類的特定方法,name 參

數(shù)指定方法的名字,parameterTypes參數(shù)指定方法的參數(shù)類型。

getConstrutors():獲得類的public類型的構造方法。

getConstrutor(Class[] parameterTypes):獲得類的特定構造方法,parameterTypes參數(shù)指定構造方法的參數(shù)類型。

如例程3 所示的InvokeTester 類的main()方法中,運用反射機制調用一個

InvokeTester 對象的add()和echo()方法。

例程3 InvokeTester.java

Java代碼

 
 
 
  1. import java.lang.reflect.*;     
  2.     
  3. public class InvokeTester {     
  4.     public int add(int param1, int param2) {     
  5.         return param1 + param2;     
  6.     }     
  7.     
  8.     public String echo(String msg) {     
  9.         return "echo:" + msg;     
  10.     }     
  11.     
  12.     public static void main(String[] args) throws Exception {     
  13.         Class classType = InvokeTester.class;     
  14.         Object invokeTester = classType.newInstance();     
  15.         // 調用InvokeTester對象的add()方法     
  16.         Method addMethod = classType.getMethod("add", new Class[] { int.class,     
  17.                 int.class });     
  18.         Object result = addMethod.invoke(invokeTester, new Object[] {     
  19.                 new Integer(100), new Integer(200) });     
  20.         System.out.println((Integer) result);     
  21.         // 調用InvokeTester對象的echo()方法     
  22.         Method echoMethod = classType.getMethod("echo",     
  23.                 new Class[] { String.class });     
  24.         result = echoMethod.invoke(invokeTester, new Object[] { "Hello" });     
  25.         System.out.println((String) result);     
  26.     }     
  27. }    

執(zhí)行結果:300

echo:Hello

add()方法的兩個參數(shù)為int 類型,獲得表示add()方法的Method對象的代碼如下:

Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});

Method類的invoke(Object obj,Object args[])方法接收的參數(shù)必須為對象,如果參數(shù)為基本類型數(shù)據(jù),必須轉換為相應的包裝類型的對象。invoke()方法的返回值總是對象,

如果實際被調用的方法的返回類型是基本類型數(shù)據(jù),那么invoke()方法會把它轉換為相

應的包裝類型的對象,再將其返回。

在本例中,盡管InvokeTester 類的add()方法的兩個參數(shù)及返回值都是int 類型,調

用addMethod對象的invoke()方法時,只能傳遞Integer 類型的參數(shù),并且invoke()方法的返回類型也是Integer 類型,Integer 類是int 基本類型的包裝類:

Object result=addMethod.invoke(invokeTester,

new Object[]{new Integer(100),new Integer(200)});

System.out.println((Integer)result); //result 為Integer類型

java.lang.Array 類提供了動態(tài)創(chuàng)建和訪問數(shù)組元素的各種靜態(tài)方法。如例程10-4

所示的ArrayTester1 類的main()方法創(chuàng)建了一個長度為10 的字符串數(shù)組,接著把索引

位置為5 的元素設為“hello”,然后再讀取索引位置為5 的元素的值。

例程10-4 ArrayTester1.java

Java代碼

 
 
 
  1. import java.lang.reflect.*;     
  2.     
  3. public class ArrayTester1 {     
  4.     public static void main(String args[]) throws Exception {     
  5.         Class classType = Class.forName("java.lang.String");     
  6.         // 創(chuàng)建一個長度為10 的字符串數(shù)組     
  7.         Object array = Array.newInstance(classType, 10);     
  8.         // 把索引位置為5 的元素設為"hello"     
  9.         Array.set(array, 5, "hello");     
  10.         // 讀取索引位置為5 的元素的值     
  11.         String s = (String) Array.get(array, 5);     
  12.         System.out.println(s); //輸出hello     
  13.     }     
  14. }    

如例程10-5 所示的ArrayTester2 類的main()方法創(chuàng)建了一個5×10×15 的整型數(shù)

組,并把索引位置為[3][5][10]的元素的值為設37。

Java代碼

 
 
 
  1. import java.lang.reflect.*;     
  2.     
  3. public class ArrayTester2 {     
  4.     public static void main(String args[]) {     
  5.         int dims[] = new int[] { 5, 10, 15 };     
  6.         Object array = Array.newInstance(Integer.TYPE, dims);     
  7.         // 使arrayObj 引用array[3]     
  8.         Object arrayObj = Array.get(array, 3);     
  9.         Class cls = arrayObj.getClass().getComponentType();     
  10.         System.out.println(cls);     
  11.         // 使arrayObj 引用array[3][5]     
  12.         arrayObj = Array.get(arrayObj, 5);     
  13.         // 把元素array[3][5][10]設為37     
  14.         Array.setInt(arrayObj, 10, 37);     
  15.         int arrayCast[][][] = (int[][][]) array;     
  16.         System.out.println(arrayCast[3][5][10]);     
  17.     }     
  18. }    

輸出:

class [I

37???

【編輯推薦】

  1. 深入剖析JAVA反射機制強大功能
  2. 關于Java反射機制的一個實例
  3. Java編譯過程與c/c++編譯過程有何不同
  4. Java虛擬機發(fā)展回顧 為跨平臺而生
  5. Java虛擬機(JVM)中的內存設置詳解

網站名稱:詳解Java反射機制實例
瀏覽路徑:http://www.dlmjj.cn/article/cojdjjs.html