您好,登錄后才能下訂單哦!
本篇內容主要講解“Java內省機制怎么實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java內省機制怎么實現”吧!
在實際編程中,我們常常需要一些用來包裝值對象的類,例如Student、 Employee、Order,這些 類中往往沒有業務方法,只是為了把需要處理的實體對象進行封裝,有這樣的特征:
屬性都是私有的;
有無參的public構造方法;
對私有屬性根據需要提供公有的getXxx方法以及setXxx方法;
比如:屬性名稱為name,則有getName方法返回屬性name值, setName方法設置name值;注意方法的名稱通常是get或 set加上屬性名稱,并把屬性名稱的首字母大寫;這些方法稱為getters/setters;getters必須有返回值沒有方法參數; setter值沒有返回值,有方法參數;
例如下面的例子:
符合這些特征的類,被稱為JavaBean;
內省(Inspector)機制就是基于反射的基礎, Java語言對Bean類屬性、事件的一種缺省處理方法。
只要類中有getXXX方法,或者setXXX方法,或者同時有getXXX及setXXX方法,其中getXXX方 法沒有方法參數,有返回值; setXXX方法沒有返回值,有一個方法參數;那么內省機制就認為 XXX為一個屬性;
例如下面代碼
Employee類中根本沒有聲明age屬性,僅僅是聲明了這樣的getter和setter.內省機制就認為age是屬性
package com.shixun.introspector; public class Employee { private String name; private Double score; // age將被內省認為是屬性 public int getAge(){ return 30; } // name將被內省認為是屬性 public String getName() { return name; } public void setName(String name) { this.name = name; } // score將被內省認為是屬性 public Double getScore() { return score; } public void setScore(Double score) { this.score = score; } public static void main(String[] args) { } }
與Java內省有關的主要類及接口有:
java.beans.Introspector類
: 為獲得JavaBean屬性、事件、方法提供了標準方法;通常使用其中的getBeanInfo方法返回BeanInfo對象;
Java.beans.BeanInfo接口
:不能直接實例化,通常通過Introspector類返回該類型對象,提供了返回屬性描述符對象(PropertyDescriptor)、方法描述符對象(MethodDescriptor) 、 bean描述符(BeanDescriptor)對象的方法;
Java.beans.PropertyDescriptor類
:用來描述一個屬性,該屬性有getter及setter方法;
可以使用PropertyDescriptor類的方法獲取屬性相關的信息,例如getName方法返回屬性的名字:
PropertyDescriptor類中定義了方法可以獲取該屬性的getter和setter方法
方法 | 方法描述 |
---|---|
Method getReadMethod() | 回屬性對應的getter方法對象; |
Method getWriteMethod() | 回屬性對應的setter方法對象; |
下面我們來用代碼深入探究一下:
Employee如上面代碼所示,繼續編寫主函數進行測試
首先用BeanInfo接口獲取BeanInfo的對象,再通過BeanInfo對象獲取PropertyDescriptor屬性描述
//獲取BeanInfo的對象 BeanInfo employeeBeanInfo = Introspector.getBeanInfo(Employee.class); //通過BeanInfo對象獲取PropertyDescriptor屬性描述 PropertyDescriptor[] propertyDescriptors = employeeBeanInfo.getPropertyDescriptors(); System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ===================="); Arrays.stream(propertyDescriptors).forEach(f->{ System.out.println("===================================="); System.out.println("屬性名:"+f.getName()); System.out.println("類型:"+f.getPropertyType()); System.out.println("get方法:"+f.getReadMethod()); System.out.println("set方法:"+f.getWriteMethod()); }); // 或者用增強for System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ===================="); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { System.out.println("===================================="); System.out.println("名字:" + propertyDescriptor.getName()); System.out.println("類型:" + propertyDescriptor.getPropertyType()); System.out.println("get方法:" + propertyDescriptor.getReadMethod()); System.out.println("set方法:" + propertyDescriptor.getWriteMethod()); }
運行結果如下:
我們也可以通過反射調用這里獲取的get或set方法
//創建Employee的對象 Class<?> clazz = Class.forName("com.shixun.introspector.Employee"); Object employee = clazz.newInstance(); //遍歷屬性描述對象 for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { //打印屬性名稱 System.out.println(propertyDescriptor.getName()); //判斷屬性名稱是不是name if (propertyDescriptor.getName().equals("name")) { //setter方法 Method writeMethod = propertyDescriptor.getWriteMethod(); //調用setName方法 writeMethod.invoke(employee, "jack"); //getter方法 Method readMethod = propertyDescriptor.getReadMethod(); //調用getName方法 Object nameValue = readMethod.invoke(employee); System.out.println("name屬性的值為:" + nameValue); } //判斷屬性名稱是否為score if (propertyDescriptor.getName().equals("score")) { //setter方法 Method scoreWriteMethod = propertyDescriptor.getWriteMethod(); //調用setScore方法 scoreWriteMethod.invoke(employee, new Double(3000)); //getter方法 Method scoreReadMethod = propertyDescriptor.getReadMethod(); Object scoreValue = scoreReadMethod.invoke(employee); System.out.println("score屬性的值為:" + scoreValue); } } System.out.println("當前對象的信息:"+employee.toString());
運行結果如下所示:
全部代碼附在最下方!!!!!!
很多框架都使用了內省機制檢索對象的屬性,定義屬性名字時,名字最好起碼以兩個小寫字母開頭,例如stuName,而不要使用sName,某些情況下,可能會導致檢索屬性失敗;
內省機制檢索屬性時,是根據getter和setter方法確認屬性名字,而不是根據類里聲明的成員變量名稱決定;
package com.shixun.introspector; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; public class Employee { private String name; private Double score; // age將被內省認為是屬性 public int getAge() { return 30; } // name將被內省認為是屬性 public String getName() { return name; } public void setName(String name) { this.name = name; } // score將被內省認為是屬性 public Double getScore() { return score; } public void setScore(Double score) { this.score = score; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", score=" + score + '}'; } public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException { //獲取BeanInfo的對象 BeanInfo employeeBeanInfo = Introspector.getBeanInfo(Employee.class); //通過BeanInfo對象獲取PropertyDescriptor屬性描述 PropertyDescriptor[] propertyDescriptors = employeeBeanInfo.getPropertyDescriptors(); // System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ===================="); // Arrays.stream(propertyDescriptors).forEach(f->{ // System.out.println("===================================="); // System.out.println("屬性名:"+f.getName()); // System.out.println("類型:"+f.getPropertyType()); // System.out.println("get方法:"+f.getReadMethod()); // System.out.println("set方法:"+f.getWriteMethod()); // }); // // // // System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ===================="); // // for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { // System.out.println("名字:" + propertyDescriptor.getName()); // System.out.println("類型:" + propertyDescriptor.getPropertyType()); // System.out.println("get方法:" + propertyDescriptor.getReadMethod()); // System.out.println("set方法:" + propertyDescriptor.getWriteMethod()); // } //創建Employee的對象 Class<?> clazz = Class.forName("com.shixun.introspector.Employee"); Object employee = clazz.newInstance(); //遍歷屬性描述對象 for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { //打印屬性名稱 System.out.println(propertyDescriptor.getName()); //判斷屬性名稱是不是name if (propertyDescriptor.getName().equals("name")) { //setter方法 Method writeMethod = propertyDescriptor.getWriteMethod(); //調用setName方法 writeMethod.invoke(employee, "jack"); //getter方法 Method readMethod = propertyDescriptor.getReadMethod(); //調用getName方法 Object nameValue = readMethod.invoke(employee); System.out.println("name屬性的值為:" + nameValue); } //判斷屬性名稱是否為score if (propertyDescriptor.getName().equals("score")) { //setter方法 Method scoreWriteMethod = propertyDescriptor.getWriteMethod(); //調用setScore方法 scoreWriteMethod.invoke(employee, new Double(3000)); //getter方法 Method scoreReadMethod = propertyDescriptor.getReadMethod(); Object scoreValue = scoreReadMethod.invoke(employee); System.out.println("score屬性的值為:" + scoreValue); } } System.out.println("當前對象的信息:"+employee.toString()); } }
到此,相信大家對“Java內省機制怎么實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。