欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
java反射機制與動(dòng)態(tài)代理(一)

前言,在Java運行時(shí)刻,能否知道一個(gè)類(lèi)的屬性方法并調用改動(dòng)之?對于任意一個(gè)對象,能否知道他的所屬類(lèi),并調用他的方法?答案是肯定的。這種動(dòng)態(tài)的獲取信息及動(dòng)態(tài)調用方法的機制在Java中稱(chēng)為“反射”(reflection)。

Java反射機制主要提供以下功能:

在運行時(shí)判斷任意一個(gè)對象所屬的類(lèi);
在運行時(shí)構造任意一個(gè)類(lèi)的對象;
在運行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法;
在運行時(shí)調用任意一個(gè)對象的方法。

Reflection 是Java被視為動(dòng)態(tài)(或準動(dòng)態(tài))語(yǔ)言的一個(gè)關(guān)鍵性質(zhì)。這個(gè)機制允許程序在運行時(shí)透過(guò)Reflection APIs取得任何一個(gè)已知名稱(chēng)的class的內部信息,包括其modifiers(諸如public, static 等等)、superclass(例如Object)、實(shí)現之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于運行時(shí)改變fields內容或調用methods。

 

一般而言,開(kāi)發(fā)者社群說(shuō)到動(dòng)態(tài)語(yǔ)言,大致認同的一個(gè)定義是:“程序運行時(shí),允許改變程序結構或變量類(lèi)型,這種語(yǔ)言稱(chēng)為動(dòng)態(tài)語(yǔ)言”。

 

在JDK中,主要由以下類(lèi)來(lái)實(shí)現Java反射機制,這些類(lèi)都位于java.lang.reflect包中:
Class類(lèi):代表一個(gè)類(lèi);
Field 類(lèi):代表類(lèi)的成員變量(成員變量也稱(chēng)為類(lèi)的屬性);
Method類(lèi):代表類(lèi)的方法;
Constructor 類(lèi):代表類(lèi)的構造方法;
Array類(lèi):提供了動(dòng)態(tài)創(chuàng )建數組,以及訪(fǎng)問(wèn)數組的元素的靜態(tài)方法;

 

例程DateMethodsTest類(lèi)演示了Reflection API的基本作用,它讀取命令行參數指定的類(lèi)名,然后打印這個(gè)類(lèi)所具有的方法信息,代碼如下:

Datemethodstest.java代碼
  1. public class DateMethodsTest      
  2. {      
  3.     public static void main(String args[]) throws Exception      
  4.     {      
  5.         // 加載并初始化命令行參數指定的類(lèi)      
  6.         Class<?> classType = Class.forName("java.util.Date");      
  7.         // 獲得類(lèi)的所有方法      
  8.         Method methods[] = classType.getDeclaredMethods();      
  9.         for (int i = 0; i < methods.length; i++)      
  10.         {      
  11.             System.out.println(methods[i].toString());      
  12.         }      
  13.     }      
  14. }    

 

例程ReflectTester類(lèi)進(jìn)一步演示了Reflection API的基本使用方法。ReflectTester類(lèi)有一個(gè)copy(Object object)方法,這個(gè)方法能夠創(chuàng )建一個(gè)和參數object同樣類(lèi)型的對象,然后把object對象中的所有屬性拷貝到新建的對象中,并將它返回這個(gè)例子只能復制簡(jiǎn)單的JavaBean,假定JavaBean 的每個(gè)屬性都有public 類(lèi)型的getXXX()和setXXX()方法,代碼如下:

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

 

ReflectTester 類(lèi)的copy(Object object)方法依次執行以下步驟:


(1)獲得對象的類(lèi)型:
Class classType=object.getClass();
System.out.println("Class:"+classType.getName());

 

在java.lang.Object 類(lèi)中定義了getClass()方法,因此對于任意一個(gè)Java對象,都可以通過(guò)此方法獲得對象的類(lèi)型。Class類(lèi)是Reflection API 中的核心類(lèi),它有以下方法:
getName():獲得類(lèi)的完整名字;
getFields():獲得類(lèi)的public類(lèi)型的屬性;
getDeclaredFields():獲得類(lèi)的所有屬性;
getMethods():獲得類(lèi)的public類(lèi)型的方法;
getDeclaredMethods():獲得類(lèi)的所有方法;

 

getMethod(String name, Class[] parameterTypes):獲得類(lèi)的特定方法,name參數指定方法的名字,parameterTypes 參數指定方法的參數類(lèi)型;

getConstructors():獲得類(lèi)的public類(lèi)型的構造方法;
getConstructor(Class[] parameterTypes):獲得類(lèi)的特定構造方法,parameterTypes 參數指定構造方法的參數類(lèi)型;
newInstance():通過(guò)類(lèi)的不帶參數的構造方法創(chuàng )建這個(gè)類(lèi)的一個(gè)對象;

 

(2)通過(guò)默認構造方法創(chuàng )建一個(gè)新對象:
Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
以上代碼先調用Class類(lèi)的getConstructor()方法獲得一個(gè)Constructor 對象,它代表默認的構造方法,然后調用Constructor對象的newInstance()方法構造一個(gè)實(shí)例。

 

(3)獲得對象的所有屬性:
Field fields[]=classType.getDeclaredFields();
Class 類(lèi)的getDeclaredFields()方法返回類(lèi)的所有屬性,包括public、protected、默認和private訪(fǎng)問(wèn)級別的屬性。

 

(4)獲得每個(gè)屬性相應的getXXX()和setXXX()方法,然后執行這些方法,把原來(lái)對象的屬性拷貝到新的對象中。

 

以上是一個(gè)反射(reflection)的比較詳細的解說(shuō),當然真正工程上是不會(huì )這樣麻煩的,這里是底層的講解。

 

 

以下這個(gè)類(lèi)運用反射機制調用其add()和echo()方法,代碼如下:

Invoketester.java代碼
  1. import java.lang.reflect.Method;      
  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.      
  16.         // 調用InvokeTester對象的add()方法      
  17.         Method addMethod = classType.getMethod("add", new Class[] { int.class,      
  18.                 int.class });      
  19.         Object result = addMethod.invoke(invokeTester, new Object[] {      
  20.                 new Integer(100), new Integer(200) });      
  21.         System.out.println((Integer) result);      
  22.      
  23.         // 調用InvokeTester對象的echo()方法      
  24.         Method echoMethod = classType.getMethod("echo",      
  25.                 new Class[] { String.class });      
  26.         result = echoMethod.invoke(invokeTester, new Object[] { "Hello" });      
  27.         System.out.println((String) result);      
  28.     }      
  29. }    

 

add()方法的兩個(gè)參數為int 類(lèi)型,獲得表示add()方法的Method對象的代碼如下:
Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});
Method類(lèi)的invoke(Object obj,Object args[])方法接收的參數必須為對象,如果參數為基本類(lèi)型數據,必須轉換為相應的包裝類(lèi)型的對象。invoke()方法的返回值總是對象,如果實(shí)際被調用的方法的返回類(lèi)型是基本類(lèi)型數據,那么invoke()方法會(huì )把它轉換為相應的包裝類(lèi)型的對象,再將其返回。

 

在本例中,盡管InvokeTester 類(lèi)的add()方法的兩個(gè)參數以及返回值都是int類(lèi)型,調用add Method 對象的invoke()方法時(shí),只能傳遞Integer 類(lèi)型的參數,并且invoke()方法的返回類(lèi)型也是Integer 類(lèi)型,Integer 類(lèi)是int 基本類(lèi)型的包裝類(lèi):

Object result=addMethod.invoke(invokeTester,
new Object[]{new Integer(100),new Integer(200)});
System.out.println((Integer)result); //result 為Integer類(lèi)型。

 

java.lang.Array 類(lèi)提供了動(dòng)態(tài)創(chuàng )建和訪(fǎng)問(wèn)數組元素的各種靜態(tài)方法。下面的例子ArrayTester1.java的main()方法創(chuàng )建了一個(gè)長(cháng)度為10 的字符串數組,接著(zhù)把索引位置為5 的元素設為“hello”,然后再讀取索引位置為5 的元素的值,代碼如下:

Arraytester1.java代碼
  1. import java.lang.reflect.Array;      
  2.      
  3. public class ArrayTester1      
  4. {      
  5.     public static void main(String args[]) throws Exception      
  6.     {      
  7.         Class<?> classType = Class.forName("java.lang.String");      
  8.         // 創(chuàng )建一個(gè)長(cháng)度為10的字符串數組      
  9.         Object array = Array.newInstance(classType, 10);      
  10.         // 把索引位置為5的元素設為"hello"      
  11.         Array.set(array, 5"hello");      
  12.         // 獲得索引位置為5的元素的值      
  13.         String s = (String) Array.get(array, 5);      
  14.         System.out.println(s);      
  15.     }      
  16. }   

 

Java API是個(gè)很好的幫助資料,大家可以查閱觀(guān)看。比如說(shuō)以上的例子:classType就是String類(lèi)型的一個(gè)對象。通過(guò)Array類(lèi)的newInstance(類(lèi)型, 長(cháng)度)創(chuàng )建了一個(gè)長(cháng)度為10的,類(lèi)型為String的Array數組。通過(guò)Array的get和set方法可以將字符串“hello”插進(jìn)下標為5(實(shí)際上是Array中第六個(gè)元素)的“數組方塊”中。

 

下面例子是一個(gè)復雜的多維數組例子,不過(guò)只要了解了一維數組,應該不難了解多維數組的。所謂多維數組只是下級數組作為一個(gè)“元素”存在于上級數組中。

 

例程ArrayTester2 類(lèi)的main()方法創(chuàng )建了一個(gè) 5 x 10 x 15 的整型數組,并把索引位置為[3][5][10] 的元素的值為設37,代碼如下:

Arraytester2.java代碼
  1. import java.lang.reflect.Array;      
  2.      
  3. public class ArrayTester2      
  4. {      
  5.     public static void main(String args[])      
  6.     {      
  7.         int[] dims = new int[] { 51015 };      
  8.         Object array = Array.newInstance(Integer.TYPE, dims);      
  9.         Object arrayObj = Array.get(array, 3);      
  10.         Class<?> cls = arrayObj.getClass().getComponentType();      
  11.         System.out.println(cls);      
  12.         arrayObj = Array.get(arrayObj, 5);      
  13.         Array.setInt(arrayObj, 1037);      
  14.         int arrayCast[][][] = (int[][][]) array;      
  15.         System.out.println(arrayCast[3][5][10]);      
  16.     }      
  17. }   

 Class是Reflection起源。針對任何您想探勘的class,唯有先為它產(chǎn)生一個(gè)Class object,接下來(lái)才能經(jīng)由后者喚起為數十多個(gè)的Reflection APIs。

 

Java允許我們從多種途徑為一個(gè)class生成對應的Class object。

 

(一)運用getClass()方法:

String str = "abc";

Class class = str.getClass();

 

(二)運用Class.getSuperclass()方法:

Button b = new Button();

Class c1 = b.getSuperclass();

Class c2 = c1.getSuperclass();

 

(三)運用靜態(tài)方法Class.forName(),這個(gè)最常用:

Class c1 = Class.forName("java.lang.String");

Class c2 = Class.forName("java.util.Date");

 

(四)運用.class語(yǔ)法:

Class c1 = String.class;

Class c2 = java.awt.Button.class;

Class c3 = int.class;

Class C4 = int[].class;

 

(五)運用原始包裝類(lèi)的TYPE方法:

Class c1 = Integer.TYPE;

Class c2 = Character.TYPE;

Class c3 = Boolean.TYPE;

Class c4 = Void.TYPE;

 

通過(guò)這五種方法,可以生成我們想要的類(lèi)對象。

 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Java網(wǎng)絡(luò )編程精解之Java語(yǔ)言的反射機制一
JAVA語(yǔ)言中的反射機制
java 反射常用方法
java反射機制method用法
Java反射機制詳解AAA
泛型
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久