日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java bean的反射类_JAVA中反射机制五(JavaBean的内省与BeanUtils库)

發(fā)布時(shí)間:2023/12/19 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java bean的反射类_JAVA中反射机制五(JavaBean的内省与BeanUtils库) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

內(nèi)省(Introspector) 是Java?語言對(duì)JavaBean類屬性、事件的一種缺省處理方法。

JavaBean是一種特殊的類,主要用于傳遞數(shù)據(jù)信息,這種類中的方法主要用于訪問私有的字段,且方法名符合某種命名規(guī)則。如果在兩個(gè)模塊之間傳遞信息,可以將信息封裝進(jìn)JavaBean中,這種對(duì)象稱為“值對(duì)象”(Value Object),或“VO”。方法比較少。這些信息儲(chǔ)存在類的私有變量中,通過set()、get()獲得。

例如類UserInfo :

package com.peidasoft.instrospector;

public class UserInfo {

private long userId;

private String userName;

private int age;

private String emailAddress;

public long getUserId() {

return userId;

}

public void setUserId(long userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getEmailAddress() {

return emailAddress;

}

public void setEmailAddress(String emailAddress) {

this.emailAddress = emailAddress;

}

}

在類UserInfo中有屬性u(píng)serName,那我們可以通過getUserName,?setUserName來得到其值或者設(shè)置新的值。通過getUserName/setUserName來訪問userName屬性,這就是默認(rèn)的規(guī)則。Java?JDK中提供了一套API用來訪問某個(gè)屬性的getter/setter方法,這就是內(nèi)省。

JDK內(nèi)省類庫(kù):

PropertyDescriptor類:(屬性描述器)

PropertyDescriptor類表示JavaBean類通過存儲(chǔ)器導(dǎo)出一個(gè)屬性。主要方法:

1. getPropertyType(),獲得屬性的Class對(duì)象;

2. getReadMethod(),獲得用于讀取屬性值的方法;

3. getWriteMethod(),獲得用于寫入屬性值的方法;

4. hashCode(),獲取對(duì)象的哈希值;

5. setReadMethod(Method readMethod),設(shè)置用于讀取屬性值的方法;

6. setWriteMethod(Method writeMethod),設(shè)置用于寫入屬性值的方法。

實(shí)例代碼如下:

package com.peidasoft.instrospector;

import java.beans.BeanInfo;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.Method;

public class BeanInfoUtil {

// 設(shè)置bean的某個(gè)屬性值

public static void setProperty(UserInfo userInfo, String userName) throws Exception {

// 獲取bean的某個(gè)屬性的描述符

PropertyDescriptor propDesc = new PropertyDescriptor(userName, UserInfo.class);

// 獲得用于寫入屬性值的方法

Method methodSetUserName = propDesc.getWriteMethod();

// 寫入屬性值

methodSetUserName.invoke(userInfo, "wong");

System.out.println("set userName:" + userInfo.getUserName());

}

// 獲取bean的某個(gè)屬性值

public static void getProperty(UserInfo userInfo, String userName) throws Exception {

// 獲取Bean的某個(gè)屬性的描述符

PropertyDescriptor proDescriptor = new PropertyDescriptor(userName, UserInfo.class);

// 獲得用于讀取屬性值的方法

Method methodGetUserName = proDescriptor.getReadMethod();

// 讀取屬性值

Object objUserName = methodGetUserName.invoke(userInfo);

System.out.println("get userName:" + objUserName.toString());

}

}

Introspector類:

將JavaBean中的屬性封裝起來進(jìn)行操作。在程序把一個(gè)類當(dāng)做JavaBean來看,就是調(diào)用Introspector.getBeanInfo()方法,得到的BeanInfo對(duì)象封裝了把這個(gè)類當(dāng)做JavaBean看的結(jié)果信息,即屬性的信息。

getPropertyDescriptors(),獲得屬性的描述,可以采用遍歷BeanInfo的方法,來查找、設(shè)置類的屬性。具體代碼如下:

import java.beans.BeanInfo;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.Method;

public class BeanInfoUtil {

// 通過內(nèi)省設(shè)置bean的某個(gè)屬性值

public static void setPropertyByIntrospector(UserInfo userInfo, String userName) throws Exception {

// 獲取bean信息

BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);

// 獲取bean的所有屬性列表

PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();

// 遍歷屬性列表,查找指定的屬性

if (proDescrtptors != null && proDescrtptors.length > 0) {

for (PropertyDescriptor propDesc : proDescrtptors) {

// 找到則寫入屬性值

if (propDesc.getName().equals(userName)) {

Method methodSetUserName = propDesc.getWriteMethod();

methodSetUserName.invoke(userInfo, "alan"); // 寫入屬性值

System.out.println("set userName:" + userInfo.getUserName());

break;

}

}

}

}

// 通過內(nèi)省獲取bean的某個(gè)屬性值

public static void getPropertyByIntrospector(UserInfo userInfo, String userName) throws Exception {

BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);

PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();

if (proDescrtptors != null && proDescrtptors.length > 0) {

for (PropertyDescriptor propDesc : proDescrtptors) {

if (propDesc.getName().equals(userName)) {

Method methodGetUserName = propDesc.getReadMethod();

Object objUserName = methodGetUserName.invoke(userInfo);

System.out.println("get userName:" + objUserName.toString());

break;

}

}

}

}

}

通過這兩個(gè)類的比較可以看出,都是需要獲得PropertyDescriptor,只是方式不一樣:前者通過創(chuàng)建對(duì)象直接獲得,后者需要遍歷,所以使用PropertyDescriptor類更加方便。

package com.peidasoft.instrospector;

public class BeanInfoTest {

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

UserInfo userInfo = new UserInfo();

userInfo.setUserName("peida");

try {

BeanInfoUtil.getProperty(userInfo, "userName");

BeanInfoUtil.setProperty(userInfo, "userName");

BeanInfoUtil.getProperty(userInfo, "userName");

BeanInfoUtil.setPropertyByIntrospector(userInfo, "userName");

BeanInfoUtil.getPropertyByIntrospector(userInfo, "userName");

BeanInfoUtil.setProperty(userInfo, "age"); // IllegalArgumentException

} catch (Exception e) {

e.printStackTrace();

}

}

}

輸出結(jié)果:

get userName:peida

set userName:wong

get userName:wong

set userName:alan

get userName:alan

java.lang.IllegalArgumentException: argument type mismatch

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:483)

at com.peidasoft.instrospector.BeanInfoUtil.setProperty(BeanInfoUtil.java:22)

at com.peidasoft.instrospector.BeanInfoTest.main(BeanInfoTest.java:26)

說明:BeanInfoUtil.setProperty(userInfo,"age");報(bào)錯(cuò)是應(yīng)為age屬性是int數(shù)據(jù)類型,而setProperty方法里面默認(rèn)給age屬性賦的值是String類型。所以會(huì)爆出argument type mismatch參數(shù)類型不匹配的錯(cuò)誤信息。

BeanUtils工具包:

由上述可看出,內(nèi)省操作非常的繁瑣,所以所以Apache開發(fā)了一套簡(jiǎn)單、易用的API來操作Bean的屬性——BeanUtils工具包。

BeanUtils工具包:下載:http://commons.apache.org/beanutils/,注意:應(yīng)用的時(shí)候還需要一個(gè)logging包http://commons.apache.org/logging/

使用BeanUtils工具包完成上面的測(cè)試代碼:

package com.peidasoft.instrospector;

import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.BeanUtils;

import org.apache.commons.beanutils.PropertyUtils;

public class BeanInfoTest {

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

UserInfo userInfo = new UserInfo();

userInfo.setUserName("peida");

try {

BeanUtils.setProperty(userInfo, "userName", "peida");

System.out.println("set userName:" + userInfo.getUserName());

System.out.println("get userName:" + BeanUtils.getProperty(userInfo, "userName"));

BeanUtils.setProperty(userInfo, "age", 18);

System.out.println("set age:" + userInfo.getAge());

System.out.println("get age:" + BeanUtils.getProperty(userInfo, "age"));

System.out.println("get userName type:" + BeanUtils.getProperty(userInfo, "userName").getClass().getName());

System.out.println("get age type:" + BeanUtils.getProperty(userInfo, "age").getClass().getName());

PropertyUtils.setProperty(userInfo, "age", 8);

System.out.println(PropertyUtils.getProperty(userInfo, "age"));

System.out.println(PropertyUtils.getProperty(userInfo, "age").getClass().getName());

PropertyUtils.setProperty(userInfo, "age", "8"); // IllegalArgumentException

} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {

e.printStackTrace();

}

}

}

運(yùn)行結(jié)果:

[java] view plain copy

set userName:peida

get userName:peida

set age:18

get age:18

get userName type:java.lang.String

get age type:java.lang.String

8

java.lang.Integer

Exception in thread "main" java.lang.IllegalArgumentException: Cannot invoke com.peidasoft.instrospector.UserInfo.setAge on bean class

'class com.peidasoft.instrospector.UserInfo' - argument type mismatch - had objects of type "java.lang.String" but expected signature "int"

at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2181)

at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2097)

at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1903)

at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:2010)

at org.apache.commons.beanutils.PropertyUtils.setProperty(PropertyUtils.java:896)

at com.peidasoft.instrospector.BeanInfoTest.main(BeanInfoTest.java:32)

Caused by: java.lang.IllegalArgumentException: argument type mismatch

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:483)

at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2116)

... 5 more

說明:

1. 獲得屬性的值,例如,BeanUtils.getProperty(userInfo, "userName"),返回字符串。

2. 設(shè)置屬性的值,例如,BeanUtils.setProperty(userInfo, "age", 8),參數(shù)是字符串或基本類型自動(dòng)包裝。設(shè)置屬性的值是字符串,獲得的值也是字符串,不是基本類型。   3. BeanUtils的特點(diǎn):

1). 對(duì)基本數(shù)據(jù)類型的屬性的操作:在WEB開發(fā)、使用中,錄入和顯示時(shí),值會(huì)被轉(zhuǎn)換成字符串,但底層運(yùn)算用的是基本類型,這些類型轉(zhuǎn)到動(dòng)作由BeanUtils自動(dòng)完成。

2). 對(duì)引用數(shù)據(jù)類型的屬性的操作:首先在類中必須有對(duì)象,不能是null,例如,private Date birthday=new Date();。操作的是對(duì)象的屬性而不是整個(gè)對(duì)象,例如,BeanUtils.setProperty(userInfo, "birthday.time", 111111);

package com.peidasoft.Introspector;

import java.util.Date;

public class UserInfo {

private Date birthday = new Date(); // 引用類型的屬性,不能為null

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

public Date getBirthday() {

return birthday;

}

}

package com.peidasoft.Beanutil;

import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.BeanUtils;

import com.peidasoft.Introspector.UserInfo;

public class BeanUtilTest {

public static void main(String[] args) {

UserInfo userInfo=new UserInfo();

try {

BeanUtils.setProperty(userInfo, "birthday.time","111111"); // 操作對(duì)象的屬性,而不是整個(gè)對(duì)象

Object obj = BeanUtils.getProperty(userInfo, "birthday.time");

System.out.println(obj);

}

catch (IllegalAccessException e) {

e.printStackTrace();

}

catch (InvocationTargetException e) {

e.printStackTrace();

}

catch (NoSuchMethodException e) {

e.printStackTrace();

}

}

}

3. PropertyUtils類和BeanUtils不同在于,運(yùn)行g(shù)etProperty、setProperty操作時(shí),沒有類型轉(zhuǎn)換,使用屬性的原有類型或者包裝類。由于age屬性的數(shù)據(jù)類型是int,所以方法PropertyUtils.setProperty(userInfo,"age", "8")會(huì)爆出數(shù)據(jù)類型不匹配,無法將值賦給屬性。

聲明本文轉(zhuǎn)自:http://blog.csdn.net/zhoudaxia/article/details/33783321

總結(jié)

以上是生活随笔為你收集整理的java bean的反射类_JAVA中反射机制五(JavaBean的内省与BeanUtils库)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。