内省
内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包java.beans 中。
一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子,这个例子把某个对象的所有属性名称和值都打印出来:
也就是说给定一个javabean对象,我们就可以得到/调用它的所有的get/set方法
package com.part_22.p11;
import java.awt.event.ActionListener;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
/**
* java内省
*/
public class IntrospectorDemo
{
public static void main(String[] args) throws Exception
{
Student s = new Student();
s.setName("ls");
s.setAge(1);
s.setHTML("<hmtl>");
BeanInfo info = Introspector.getBeanInfo(Student.class, Object.class);
PropertyDescriptor[] props = info.getPropertyDescriptors();//属性描述
for (int i = 0; i < props.length; i++)
//getWriteMethod()可以获得设置方法,然后采用反射去设置属性的值
System.out.println(props[i].getName() + " = " + props[i].getReadMethod().invoke(s, null));
System.out.println("-------------------");
MethodDescriptor[] methods = info.getMethodDescriptors();
for (int i = 0; i < methods.length; i++)
System.out.println(methods[i].getName());
System.out.println("-------------------");
EventSetDescriptor[] events = info.getEventSetDescriptors();
for (int i = 0; i < events.length; i++)
{
System.out.println(events[i].getListenerType().getName());
for (int j = 0; j < events[i].getListenerMethods().length; j++)
{
System.out.println(events[i].getListenerMethods()[j].getName());
}
}
}
}
class Student
{
private String name;
private int age;
private String HTML;
public void addActionListener(ActionListener al)
{
}
public void removeActionListener(ActionListener al)
{
}
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 String getHTML()
{
return HTML;
}
public void setHTML(String html)
{
HTML = html;
}
}
Web 开发框架 Struts 中的 FormBean 就是通过内省机制来将表单中的数据映射到类的属性上,因此要求 FormBean 的每个属性要有 getter/setter 方法。但也并不总是这样,什么意思呢?就是说对一个 Bean 类来讲,我可以没有属性,但是只要有 getter/setter 方法中的其中一个,那么 Java 的内省机制就会认为存在一个属性,比如类中有方法 setMobile ,那么就认为存在一个 mobile的属性,这样可以方便我们把 Bean 类通过一个接口来定义而不用去关心具体实现,不用去关心 Bean 中数据的存储。比如我们可以把所有的 getter/setter 方法放到接口里定义,但是真正数据的存取则是在具体类中去实现,这样可提高系统的扩展性。