1.内省:通过内省可以获取一个类的内部信息,方法、属性、构造函数等。
2.与反射的区别:
①内省是针对Javabean对象的,符合Javabean规则的类的成员才可以使用内省操作;反射是针对普通类的。
②内省先得到属性描述PropertyDecriptor后再进行其他操作;反射先得到类的字节码Class后再进行其他操作。
3.JavaBean:学习内省需要知道什么是javabean。
①实体类,用来封装数据、重用;
②符合一定规范书写的java类,不是一种技术而是一种规范;
③这个类是public,所有的属性为private,通过get、set方法进行访问。
④javabean实例:
package introspector;
public class Person {//javabean
private String name;//字段,提供了get或set方法的为属性
private String password;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
说明:bean到底拥有什么属性,不由字段决定,而由get或set决定。上面的例子中,这个bean共有四个属性,任何类都是object孩子,object类中有一个getclass方法,这个类继承了getclass方法,所以还有一个class属性。
一、使用内省api操作bean的属性
①使用getBeanInfo()方法,在JavaBean上进行内省,获取所有的属性、公开的方法和事件,所有属性封装到BeanInfo对象中。
②拿到BeanInfo相当于拿到bean的所有属性。
③接着调用getPropertyDescriptors()获取所有属性的属性描述器,返回的是一个数组。
④进而使用getReadMethod读取属性值,使用getReadMethod写入属性值。
实例:
(1)得到bean的所有属性
package introspector;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import org.junit.Test;
//使用内省api操作bean的属性
public class demo1 {
@Test单元测试
//得到bean的所有属性
public void test1() throws Exception{
BeanInfo info = Introspector.getBeanInfo(Person.class,Object.class);
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
System.out.println(pd.getName());
}
}
}
--上述运行结果为:
可以看到上面的结果中包含了一个class属性,是继承了父类Object而来的。
有些时候我们不想要class属性,而只要它自身的属性,该如何修改代码?
public class demo1 {
@Test
public void test1() throws Exception{
BeanInfo info = Introspector.getBeanInfo(Person.class,Object.class);//去掉(stop)想要去掉的属性
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
System.out.println(pd.getName());
}
}
}
--结果:
(2)操作bean的指定属性,以age为例:
package introspector;
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;
//使用内省api操作bean的属性
public class demo1 {
//操作bean的指定属性:age
@Test
public void test2() throws Exception{
Person p = new Person();
PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
//得到属性的写方法,为属性赋值
Method method = pd.getWriteMethod();
method.invoke(p, 20);
//获取属性的值
method = pd.getReadMethod();
System.out.println(method.invoke(p, null));
//传统方法:System.out.println(p.getAge());
}
}
(3)获取当前操作的属性的类型
public void test3() throws Exception{
Person p = new Person();
PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
System.out.println(pd.getPropertyType());}