Introspection 内省
第二个例子的运行结果:
定义:是sun公司开发的一天API。专门用来操作Java对象的属性。
第一个例子主要是针对普通内省机制。
第二个例子这是利用Beanutils工具包来访问内省机制的。
深入了解内省---beanutils工具包,
Beanutils是Apache开发的一套快速操作JavaBean getter/setter方法的API,目前来说比较流行。
准备两个包:commons-beanutils.jar (依赖于 commons-logging.jar)
可以去www.apache.org/或者直接去http://commons.apache.org/proper/commons-
beanutils/download_beanutils.cgi和http://commons.apache.org/proper/commons-
logging/download_logging.cgi下载这两个zip包。(在我上传的资源中有这两个工具包,可供下载)
注:这里不是直接将zip拷进项目用,而是需要解压后的这两个jar包。
下面举个例子:
package com.dp.java.Introspection;
import java.util.Date;
public class Introspection {
private String name="Mr_Li";
private int age=20;
private Date date;
/**
* 属性就是setter字段和getter字段的方法
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getAbc(){//属性名称就是abc,这也可以认为就是内省的本质
return "执行了abc内省变量";
}
@Override
public String toString() {
return "封装数据为:name=" + name + ", age=" + age + ", date="
+ date;
}
}
package com.dp.java.Introspection;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import org.junit.Test;
public class test {
/**
* @throws Exception
*
*/
@Test
public void test1() throws Exception {
// TODO Auto-generated method stub
//得到introspection类的属性,并封装到beaninfo对象中
BeanInfo b=Introspector.getBeanInfo(Introspection.class);
//得到类中的所有属性描述器
PropertyDescriptor[] b1=b.getPropertyDescriptors();
System.out.println(b1.length);
//在这里我们就得到了3个属性,
//而实际上我们定义了两个属性,加上一个内省属性
for(PropertyDescriptor b2:b1){
System.out.println(b2.getName());//得到属性名称
}
System.out.println("------------------");
}
@Test
public void test2() throws Exception {
// TODO Auto-generated method stub
Introspection s=new Introspection();
//PropertyDescriptor也是一个类,需要new一个属性描述器,来得到其读方法(get方法)
PropertyDescriptor p=new PropertyDescriptor("name", Introspection.class);
Method m=p.getReadMethod();
System.out.println(m.invoke(s, null));
//改变属性值呢?
Method m1=p.getWriteMethod();
m1.invoke(s, "Mr_Li");
// System.out.println(m.invoke(s, null));
System.out.println(s.getName());
}
}
第二例子:利用BeanUtils工具包框架操作属性,beanutils可以自动转化类型,但是仅限基本类型
/**
* 利用beanutils框架操作属性,beanutils可以自动转化类型,但是仅限基本类型
*/
@Test
public void test3() throws Exception{
Introspection s=new Introspection();
// TODO Auto-generated method stub
//使用BeanUtils得到属性值
String ss=BeanUtils.getProperty(s, "name");
System.out.println(ss);
//使用BeanUtils设置属性值
BeanUtils.setProperty(s, "age", 12);
//打印getAge方法
System.out.println(BeanUtils.getProperty(s, "age"));
System.out.println(s.getAge());
}
/**
* 非基本类型的转化,如下Date
*/
@Test
public void test4() throws Exception{
Introspection s=new Introspection();
/**
* 第一种方式,类型转化器
* */
//给beanUtils注册类型转化器:自定义的转化器
// ConvertUtils.register(new Converter() {
// //type:目标类型
// //value:当前传入的值
// @Override
// public Object convert(Class type, Object value) {
// // TODO Auto-generated method stub
// DateFormat df=new SimpleDateFormat("yyyy-MM-dd");
// if(value instanceof String){
// String v=(String)value;
// try {
// Date d=df.parse(v);
// } catch (ParseException e) {
// // TODO Auto-generated catch block
// throw new RuntimeException(e);
// }
// }
// else{
// //Date转化为字符串
// Date d=(Date)value;
// return df.format(d);
// }
// return df;
// }
// }, Date.class);
/**
* 第二种方式
* */
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.setProperty(s, "date", new Date());
System.out.println(s.getDate());
}
/**
* 利用Beanutils来进行封装数据(属性值),依赖HashMap。
* @throws InvocationTargetException
* @throws IllegalAccessException
* */
@Test
public void test5() throws Exception {
// TODO Auto-generated method stub
Map m=new HashMap();
m.put("name", "Mr_Li13");
m.put("age", "13");
m.put("date", new Date());
Introspection s=new Introspection();
System.out.println("封装前:"+s);
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.populate(s, m);
System.out.println("封装后:"+s);
}
第二个例子的运行结果: