自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解Java反射機制實例

開發(fā) 后端
在 Java 運行時環(huán)境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意一個對象,能否調(diào)用它的任意一個方法?答案是肯定的。這種動態(tài)獲取類的信息,以及動態(tài)調(diào)用對象的方法的功能來自于Java 語言的反(Reflection)機制。

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

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

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

了以下功能:

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

在運行時構(gòu)造任意一個類的對象;

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

在運行時調(diào)用任意一個對象的方法;

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

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

包中。

Class類:代表一個類。

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

Method類:代表類的方法。

Constructor 類:代表類的構(gòu)造方法。

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類所具有的方法,程序的打印結(jié)果如下:

 

  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對象中的所有屬性復(fù)制到新建的對象中,并將它返回。這個例子只能復(fù)制簡單的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.         // 通過默認構(gòu)造方法創(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(01).toUpperCase();     
  17.             // 獲得和屬性對應(yīng)的getXXX()方法的名字     
  18.             String getMethodName = "get" + firstLetter + fieldName.substring(1);     
  19.             // 獲得和屬性對應(yīng)的setXXX()方法的名字     
  20.             String setMethodName = "set" + firstLetter + fieldName.substring(1);     
  21.             // 獲得和屬性對應(yīng)的getXXX()方法     
  22.             Method getMethod = classType.getMethod(getMethodName,     
  23.                     new Class[] {});     
  24.             // 獲得和屬性對應(yīng)的setXXX()方法     
  25.             Method setMethod = classType.getMethod(setMethodName,     
  26.                     new Class[] { field.getType() });     
  27.             // 調(diào)用原對象的getXXX()方法     
  28.             Object value = getMethod.invoke(object, new Object[] {});     
  29.             System.out.println(fieldName + ":" + value);     
  30.             // 調(diào)用復(fù)制對象的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í)行結(jié)果: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類型的構(gòu)造方法。

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

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

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.         // 調(diào)用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.         // 調(diào)用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í)行結(jié)果: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ù),必須轉(zhuǎn)換為相應(yīng)的包裝類型的對象。invoke()方法的返回值總是對象,

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

應(yīng)的包裝類型的對象,再將其返回。

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

用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 的元素設(shè)為“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 的元素設(shè)為"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]的元素的值為設(shè)37。

Java代碼

 

 

  1. import java.lang.reflect.*;     
  2.     
  3. public class ArrayTester2 {     
  4.     public static void main(String args[]) {     
  5.         int dims[] = new int[] { 51015 };     
  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]設(shè)為37     
  14.         Array.setInt(arrayObj, 1037);     
  15.         int arrayCast[][][] = (int[][][]) array;     
  16.         System.out.println(arrayCast[3][5][10]);     
  17.     }     
  18. }    

 

輸出:

class [I

37???

【編輯推薦】

  1. 深入剖析JAVA反射機制強大功能
  2. 關(guān)于Java反射機制的一個實例
  3. Java編譯過程與c/c++編譯過程有何不同
  4. Java虛擬機發(fā)展回顧 為跨平臺而生
  5. Java虛擬機(JVM)中的內(nèi)存設(shè)置詳解
責(zé)任編輯:金賀 來源: JavaEye博客
相關(guān)推薦

2011-09-27 10:23:24

Java反射機制

2009-06-17 13:57:54

java實例Reflection

2011-04-01 14:50:56

Java的反射機制

2011-05-26 15:23:34

JavaReflection

2010-08-11 09:40:44

LINQ

2009-06-19 13:59:41

Java反射機制

2012-04-05 13:50:38

Java

2009-08-28 13:12:56

C#反射實例C#反射

2010-02-04 11:23:25

C++反射機制

2017-03-24 09:44:33

Java反射機制

2017-05-17 15:28:15

Java反射機制

2009-08-31 09:41:05

C#反射靜態(tài)方法開發(fā)

2009-04-10 09:55:44

C#反射.NET

2022-10-21 14:12:06

2012-02-08 09:44:52

Java反射

2010-09-17 13:02:11

JAVA反射機制

2022-09-26 11:03:25

Java反射漏洞

2009-06-11 08:59:35

2010-09-17 12:39:51

JAVA反射機制

2023-11-01 13:48:00

反射java
點贊
收藏

51CTO技術(shù)棧公眾號