JAVA的內省機制(introspector)與反射機制(reflection)----轉載http://yangzhibin-java.iteye.com/b...
相對而言,反射比內省更容易理解一點。用一句比較白的話來概括,反射就是讓你可以通過名稱來得到物件 ( 類,屬性,方法 ) 的技術,這種技術比內省機制使用範圍更廣泛。例如我們可以通過類名來生成一個類的例項;知道了方法名,就可以呼叫這個方法;知道了屬性名就可以訪問這個屬性的值。 內省是 Java 語言對 Bean 類屬性、事件的一種預設處理方法。例如類 A 中有屬性 name, 那我們可以通過 getName,setName 來得到其值或者設定新的值。通過 getName/setName 來訪問 name 屬性,這就是預設的規則。 Java 中提供了一套 API 用來訪問某個屬性的 getter/setter 方法,通過這些 API 可以使你不需要了解這個規則(但你最好還是要搞清楚),這些 API 存放於包 java.beans 中。
一般的做法是通過類 Introspector 來獲取某個物件的 BeanInfo 資訊,然後通過 BeanInfo 來獲取屬性的描述器( PropertyDescriptor ),通過這個屬性描述器就可以獲取某個屬性對應的 getter/setter 方法,然後我們就可以通過反射機制來呼叫這些方法。下面我們來看一個例子,這個例子把某個物件的所有屬性名稱和值都列印出來:
Java程式碼
package MyTest;
public class bean {
private String id = null ;
private String name = null ;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package MyTest;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class myBeanIntrospector {
public myBeanIntrospector()
{
try
{
//例項化一個Bean
bean beanObj = new bean();
//依據Bean產生一個相關的BeanInfo類
BeanInfo bInfoObject =
Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());
//定義一個用於顯示的字串
String output = "";
//開始自省
/*
* BeanInfo.getMethodDescriptors()
* 用於獲取該Bean中的所有允許公開的成員方法,以MethodDescriptor陣列的形式返回
*
* MethodDescriptor類
* 用於記載一個成員方法的所有資訊
* MethodDescriptor.getName()
* 獲得該方法的方法名字
* MethodDescriptor.getMethod()
* 獲得該方法的方法物件(Method類)
*
* Method類
* 記載一個具體的的方法的所有資訊
* Method.getParameterTypes()
* 獲得該方法所用到的所有引數,以Class陣列的形式返回
*
* Class..getName()
* 獲得該型別的名字
*/
output = "內省成員方法:\n";
MethodDescriptor[] mDescArray = bInfoObject.getMethodDescriptors();
for (int i=0;i<mDescArray.length ;i++ )
{
//獲得一個成員方法描述器所代表的方法的名字
String methodName = mDescArray[i].getName();
String methodParams = new String();
//獲得該方法物件
Method methodObj = mDescArray[i].getMethod();
//通過方法物件獲得該方法的所有引數,以Class陣列的形式返回
Class[] parameters = methodObj.getParameterTypes();
if (parameters.length>0)
{
//獲得引數的型別的名字
methodParams = parameters[0].getName();
for (int j=1;j<parameters.length ;j++ )
{
methodParams = methodParams + "," + parameters[j].getName();
}
}
output += methodName + "(" + methodParams + ")\n";
}
System.out.println(output);
/*
* BeanInfo.getPropertyDescriptors()
* 用於獲取該Bean中的所有允許公開的成員屬性,以PropertyDescriptor陣列的形式返回
*
* PropertyDescriptor類
* 用於描述一個成員屬性
*
* PropertyDescriptor.getName()
* 獲得該屬性的名字
*
* PropertyDescriptor.getPropertyType()
* 獲得該屬性的資料型別,以Class的形式給出
*
*/
output = "內省成員屬性:\n";
PropertyDescriptor[] mPropertyArray = bInfoObject.getPropertyDescriptors();
for (int i=0;i<mPropertyArray.length ;i++ )
{
String propertyName = mPropertyArray[i].getName();
Class propertyType = mPropertyArray[i].getPropertyType();
output += propertyName + " ( " + propertyType.getName() + " )\n";
}
System.out.println(output);
/*
* BeanInfo.getEventSetDescriptors()
* 用於獲取該Bean中的所有允許公開的成員事件,以EventSetDescriptor陣列的形式返回
*
* EventSetDescriptor類
* 用於描述一個成員事件
*
* EventSetDescriptor.getName()
* 獲得該事件的名字
*
* EventSetDescriptor.getListenerType()
* 獲得該事件所依賴的事件監聽器,以Class的形式給出
*
*/
output = "內省繫結事件:\n";
EventSetDescriptor[] mEventArray = bInfoObject.getEventSetDescriptors();
for (int i=0;i<mEventArray.length ;i++ )
{
String EventName = mEventArray[i].getName();
Class listenerType = mEventArray[i].getListenerType();
output += EventName + "(" + listenerType.getName() + ")\n";
}
System.out.println(output);
System.out.println("write by esonghui :");
}
catch (Exception e)
{
System.out.println("異常:" + e);
}
}
public static void main(String[] args)
{
new myBeanIntrospector();
}
}
一般的做法是通過類 Introspector 來獲取某個物件的 BeanInfo 資訊,然後通過 BeanInfo 來獲取屬性的描述器( PropertyDescriptor ),通過這個屬性描述器就可以獲取某個屬性對應的 getter/setter 方法,然後我們就可以通過反射機制來呼叫這些方法。下面我們來看一個例子,這個例子把某個物件的所有屬性名稱和值都列印出來:
Java程式碼
package MyTest;
public class bean {
private String id = null ;
private String name = null ;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package MyTest;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class myBeanIntrospector {
public myBeanIntrospector()
{
try
{
//例項化一個Bean
bean beanObj = new bean();
//依據Bean產生一個相關的BeanInfo類
BeanInfo bInfoObject =
Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());
//定義一個用於顯示的字串
String output = "";
//開始自省
/*
* BeanInfo.getMethodDescriptors()
* 用於獲取該Bean中的所有允許公開的成員方法,以MethodDescriptor陣列的形式返回
*
* MethodDescriptor類
* 用於記載一個成員方法的所有資訊
* MethodDescriptor.getName()
* 獲得該方法的方法名字
* MethodDescriptor.getMethod()
* 獲得該方法的方法物件(Method類)
*
* Method類
* 記載一個具體的的方法的所有資訊
* Method.getParameterTypes()
* 獲得該方法所用到的所有引數,以Class陣列的形式返回
*
* Class..getName()
* 獲得該型別的名字
*/
output = "內省成員方法:\n";
MethodDescriptor[] mDescArray = bInfoObject.getMethodDescriptors();
for (int i=0;i<mDescArray.length ;i++ )
{
//獲得一個成員方法描述器所代表的方法的名字
String methodName = mDescArray[i].getName();
String methodParams = new String();
//獲得該方法物件
Method methodObj = mDescArray[i].getMethod();
//通過方法物件獲得該方法的所有引數,以Class陣列的形式返回
Class[] parameters = methodObj.getParameterTypes();
if (parameters.length>0)
{
//獲得引數的型別的名字
methodParams = parameters[0].getName();
for (int j=1;j<parameters.length ;j++ )
{
methodParams = methodParams + "," + parameters[j].getName();
}
}
output += methodName + "(" + methodParams + ")\n";
}
System.out.println(output);
/*
* BeanInfo.getPropertyDescriptors()
* 用於獲取該Bean中的所有允許公開的成員屬性,以PropertyDescriptor陣列的形式返回
*
* PropertyDescriptor類
* 用於描述一個成員屬性
*
* PropertyDescriptor.getName()
* 獲得該屬性的名字
*
* PropertyDescriptor.getPropertyType()
* 獲得該屬性的資料型別,以Class的形式給出
*
*/
output = "內省成員屬性:\n";
PropertyDescriptor[] mPropertyArray = bInfoObject.getPropertyDescriptors();
for (int i=0;i<mPropertyArray.length ;i++ )
{
String propertyName = mPropertyArray[i].getName();
Class propertyType = mPropertyArray[i].getPropertyType();
output += propertyName + " ( " + propertyType.getName() + " )\n";
}
System.out.println(output);
/*
* BeanInfo.getEventSetDescriptors()
* 用於獲取該Bean中的所有允許公開的成員事件,以EventSetDescriptor陣列的形式返回
*
* EventSetDescriptor類
* 用於描述一個成員事件
*
* EventSetDescriptor.getName()
* 獲得該事件的名字
*
* EventSetDescriptor.getListenerType()
* 獲得該事件所依賴的事件監聽器,以Class的形式給出
*
*/
output = "內省繫結事件:\n";
EventSetDescriptor[] mEventArray = bInfoObject.getEventSetDescriptors();
for (int i=0;i<mEventArray.length ;i++ )
{
String EventName = mEventArray[i].getName();
Class listenerType = mEventArray[i].getListenerType();
output += EventName + "(" + listenerType.getName() + ")\n";
}
System.out.println(output);
System.out.println("write by esonghui :");
}
catch (Exception e)
{
System.out.println("異常:" + e);
}
}
public static void main(String[] args)
{
new myBeanIntrospector();
}
}
相關文章
- Java反射機制(轉)Java反射
- 【Android】 認識反射機制(Reflection)Android反射
- 類載入機制與反射反射
- Java的反射機制Java反射
- Java反射機制Java反射
- Java註解與反射機制Java反射
- 淺談Java —— Reflection機制(一)Java
- Java 中的 反射機制Java反射
- java 內省(Introspector)JavaROS
- Java核心反射機制Java反射
- java利器——反射機制Java反射
- Java反射機制研究Java反射
- Java反射機制實現與原理Java反射
- Java核心技術梳理-類載入機制與反射Java反射
- Java安全基礎之Java反射機制和ClassLoader類載入機制Java反射
- Java中的類反射機制Java反射
- 淺析java的反射機制Java反射
- 內省機制(操作javaBean的資訊)JavaBean
- 聊聊Java內省IntrospectorJavaROS
- (反射+內省機制的運用)處理jdbc的結果集反射JDBC
- 【JavaEE】Java內省Introspector、PropertyDescriptor與JavaBeanJavaROSBean
- Java反射機制那些事Java反射
- Java反射機制簡答Java反射
- 說說 Java 反射機制Java反射
- JAVA(五)反射機制/AnnotationJava反射
- Java 反射機制分析指南Java反射
- Java 反射機制詳解Java反射
- 分析與理解訊息反射機制 (轉)反射
- java反射機制的學習心得Java反射
- 關於Java中的反射機制Java反射
- Java 反射機制的三種方式Java反射
- java中的反射機制淺析Java反射
- JAVA中的反射機制詳解Java反射
- Java進階 | 泛型機制與反射原理Java泛型反射
- Java - 反射機制與工廠設計模式Java反射設計模式
- Java - 反射機制與單例設計模式Java反射單例設計模式
- Java筆記-反射機制(一)Java筆記反射
- java進階(41)--反射機制Java反射