内省:introSpector 内省;自省;反省;在内心省察自己;胃镜检查;(intro:介绍,简介)
它主要用于被 JavaBean 进行操作。
什么是 JavaBean?
Class Person
{
private int age;
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
java.beans
类 PropertyDescriptor
PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。属性描述符
构造方法摘要 | |
---|---|
PropertyDescriptor(String propertyName,Class<?> beanClass) 通过调用 getFoo 和 setFoo 存取方法,为符合标准 Java 约定的属性构造一个 PropertyDescriptor。 |
Method | getReadMethod() 获得应该用于读取属性值的方法。 |
Method | getWriteMethod() 获得应该用于写入属性值的方法。 |
JavaBean的简单应用方式:
package cn.itcast.day1;
public class ReflectPoint {
private int x;
public int y;
private String str1;
public String str2;
public String str3;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
public ReflectPoint(int x, int y, String str1, String str2, String str3) {
super();
this.x = x;
this.y = y;
this.str1 = str1;
this.str2 = str2;
this.str3 = str3;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String toString() {
return x + "::" + y + "::" + str1 + "::" + str2 + "::" + str3;
}
}
package cn.itcast.day1;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
// x --> X --> getX() --> methodGetX -->
//获得“x”的值,用内省的方式做:
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
Object retVal = getProperty(pt1,propertyName);
System.out.println(retVal);//3
//设置pt1的属性“x”的值:
/*PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, 7);*/
setProperty(pt1,propertyName,7);
System.out.println(pt1.getX());//将新值打印:7
}
private static Object getProperty(Object obj, String propertyName) throws Exception {
PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
Method methodGet = pd.getReadMethod();
Object reVal = methodGet.invoke(obj);
return reVal;
}
private static void setProperty( Object obj, String propertyName, Object Val) throws Exception {
PropertyDescriptor pd = new PropertyDescriptor(propertyName,obj.getClass());
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);
}
}
对JavaBean的复杂内省操作:
java.beans
类 Introspector
static BeanInfo | getBeanInfo(Class<?> beanClass) 在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。 |
static BeanInfo | getBeanInfo(Class<?> beanClass,Class<?> stopClass) 在给定的“断”点之下,在 Java Bean 上进行内省,了解其所有属性和公开的方法。 |
static BeanInfo | getBeanInfo(Class<?> beanClass, int flags) 在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件,并将结果用一些控制标记表示。 |
得到BeanInfo对象,这个BeanInfo对象就代表了整个JavaBean。BeanInfo就代表了把一个对象当做JavaBean来看的结果。
Ø得到BeanInfo最好采用“obj.getClass()”方式,而不要采用“类名.class”方式,这样程序更通用。
采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法,得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息。
package cn.itcast.day1;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
// x --> X --> getX() --> methodGetX -->
//获得“x”的值,用内省的方式做:
Object retVal = getProperty(pt1,propertyName);
System.out.println(retVal);//3
//设置pt1的属性“x”的值:
setProperty(pt1,propertyName,7);
System.out.println(pt1.getX());//将新值打印:7
}
private static Object getProperty(Object obj, String propertyName) throws Exception {
Object retVal = null;
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodGet = pd.getReadMethod();
retVal = methodGet.invoke(obj);
break;
}
}
return retVal;
}
private static void setProperty( Object obj, String propertyName, Object Val) throws Exception {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);
break;
}
}
}
}
Beanutils工具包
在阿帕奇官网下载BeanUtils工具包: http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi
下载后解压缩,在 commons-beanutils-1.9.1\apidocs 文件夹下打开 index.html 查看这个工具包的API说明文档:
我们将 commons-beanutils-1.9.1.jar 拷贝到我们的项目文件夹下的lib包中,再点击右键选择BuildPath-->add BuildPath。
static String | getProperty(Object bean,String name)
Return the value of the specified property of the specified bean, no matter which property reference format is used, as a String.
|
package cn.itcast.day1;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import org.apache.commons.beanutils.BeanUtils;
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
// x --> X --> getX() --> methodGetX -->
//获得“x”的值,用内省的方式做:
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
Object retVal = getProperty(pt1,propertyName);
System.out.println(retVal);//3
//设置pt1的属性“x”的值:
/*PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, 7);*/
setProperty(pt1,propertyName,7);
System.out.println(BeanUtils.getProperty(pt1, propertyName));//用导入第三方工具包BeanUtils的方法获取pt1类中属性“x”的值。
System.out.println(pt1.getX());//将新值打印:7
}
private static Object getProperty(Object obj, String propertyName) throws Exception {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
Method methodGet = pd.getReadMethod();
Object retVal = methodGet.invoke(obj);*/
Object retVal = null;
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodGet = pd.getReadMethod();
retVal = methodGet.invoke(obj);
break;
}
}
return retVal;
}
private static void setProperty( Object obj, String propertyName, Object Val) throws Exception {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,obj.getClass());
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);*/
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);
break;
}
}
}
}
但是我们发现没有第三方的logging会报错,于是我们再从官网下载Commons Logging
网站:http://commons.apache.org/proper/commons-logging/download_logging.cgi
下载之后解压,我们将commons-logging-1.1.3.jar文件也拷贝到项目中的lib文件夹下,并在右键Build Path子菜单中add。
add之后就会出现奶瓶状的图标:
这下就成功运行了。接下来我们还要去设置它的值:
static void | setProperty(Object bean,String name,Object value)
Set the specified property value, performing type conversions as required to conform to the type of the destination property.
|
package cn.itcast.day1;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import org.apache.commons.beanutils.BeanUtils;
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
// x --> X --> getX() --> methodGetX -->
//获得“x”的值,用内省的方式做:
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
Object retVal = getProperty(pt1,propertyName);
System.out.println(retVal);//3
//设置pt1的属性“x”的值:
/*PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, 7);*/
setProperty(pt1,propertyName,7);
System.out.println(BeanUtils.getProperty(pt1, propertyName));//用导入第三方工具包BeanUtils的方法获取pt1类中属性“x”的值。
BeanUtils.setProperty(pt1, propertyName, 9);//用导入的第三方工具包BeanUtils中的方法设置pt1类中属性“x”的值为9。
System.out.println(pt1.getX());//将新值打印
}
private static Object getProperty(Object obj, String propertyName) throws Exception {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
Method methodGet = pd.getReadMethod();
Object retVal = methodGet.invoke(obj);*/
Object retVal = null;
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodGet = pd.getReadMethod();
retVal = methodGet.invoke(obj);
break;
}
}
return retVal;
}
private static void setProperty( Object obj, String propertyName, Object Val) throws Exception {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,obj.getClass());
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);*/
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);
break;
}
}
}
}
在ReflectPoint类中加入Date类型的birthday属性,并为其添加get和set方法:
package cn.itcast.day1;
import java.util.Date;
public class ReflectPoint {
private Date birthday = new Date();
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
private int x;
public int y;
private String str1;
public String str2;
public String str3;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
public ReflectPoint(int x, int y, String str1, String str2, String str3) {
super();
this.x = x;
this.y = y;
this.str1 = str1;
this.str2 = str2;
this.str3 = str3;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String toString() {
return x + "::" + y + "::" + str1 + "::" + str2 + "::" + str3;
}
}
Date类中有setTime()方法,所以也可以把Date类看成是JavaBean,得出Date类一定有一个time属性:
void | setTime(long time) 设置此 Date 对象,以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点。 |
birthday这个属性是一个复合属性,不是一个基本属性,它本身是一个对象,它也有自己的属性。
我们为pt1这个对象的birthday属性中的time属性赋值:
package cn.itcast.day1;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
// x --> X --> getX() --> methodGetX -->
//获得“x”的值,用内省的方式做:
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
Object retVal = getProperty(pt1,propertyName);
System.out.println(retVal);//3
//设置pt1的属性“x”的值:
/*PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, 7);*/
setProperty(pt1,propertyName,7);
System.out.println(BeanUtils.getProperty(pt1, propertyName));//用导入第三方工具包BeanUtils的方法获取pt1类中属性“x”的值。
BeanUtils.setProperty(pt1, propertyName, 9);//用导入的第三方工具包BeanUtils中的方法设置pt1类中属性“x”的值为9。
System.out.println(pt1.getX());//将新值打印
BeanUtils.setProperty(pt1, "birthday.time", 111);
System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
}
private static Object getProperty(Object obj, String propertyName) throws Exception {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName, obj.getClass());
Method methodGet = pd.getReadMethod();
Object retVal = methodGet.invoke(obj);*/
Object retVal = null;
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodGet = pd.getReadMethod();
retVal = methodGet.invoke(obj);
break;
}
}
return retVal;
}
private static void setProperty( Object obj, String propertyName, Object Val) throws Exception {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,obj.getClass());
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);*/
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
if(pd.getName().equals(propertyName)) {
Method methodSet = pd.getWriteMethod();
methodSet.invoke(obj, Val);
break;
}
}
}
}
BeanUtils类中还有将一个属性的值从一个JavaBean对象身上拷贝到另一个JavaBean对象身上的相同属性名的属性身上:
static void | copyProperties(Object dest,Object orig)
Copy property values from the origin bean to the destination bean for all cases where the property names are the same.
|
static void | copyProperty(Object bean,String name,Object value)
Copy the specified property value to the specified destination bean, performing any type conversion that is required.
|
static Map<String,String> | describe(Object bean)
Return the entire set of properties for which the specified bean provides a read method.
|
相反,也提供了方法将map集合的内容填充到一个JavaBean对象里面去:
static void | populate(Object bean,Map<String,? extendsObject> properties)
Populate the JavaBeans properties of the specified bean, based on the specified name/value pairs.
|
jdk1.7新特性:定义Map的方法:????????????????????????
static Object | getProperty(Object bean,String name)
Return the value of the specified property of the specified bean, no matter which property reference format is used, with no type conversions.
|
static void | setProperty(Object bean,String name,Object value)
Set the value of the specified property of the specified bean, no matter which property reference format is used, with no type conversions.
|
它与BeanUtils的区别在于:BeanUtils是对属性的值以字符串形式操作的,传值的时候传字符串,返回也返回字符串。而PropertyUtils是对属性的值以属性本身的类型操作的,传值的时候传值本身的类型。
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net