Java中的内省
为了让程序员们更好的操作Java对象的属性,SUN公司开发了一套API,被业界内称为:内省;内省的出现有利于对类对象属性的操作,减少了代码的数量。下面用一个小例子来印证一下。
我有一个JavaBean(关于JavaBean后面会介绍)类IntroSpector,里面有一个私有的x属性,现在要得到这个x属性的值。如果我们用反射来做的话,首先你要将x字符转为大写的X,然后用字符串拼接成getX,然后你要用反射得到IntroSpector类的class,再得到类的所有公有方法,循环比较方法找出getX方法的Method对象,然后用Method对象的invoke方法得到x属性的值。这样做还是比较麻烦的。如果用内省来做就会比较简单了,方法如下:
IntroSpector is1 = new IntroSpector();
//propertyName:属性名,is1.getClass():包含属性名对象的class(与反射相关)PropertyDescriptor不明白的可以看JDK帮助文档
PropertyDescriptor pd = new PropertyDescriptor(propertyName,is1.getClass());
Method methodGetX = pd.getReadMethod();
Object getVal1 = methodGetX.invoke(is1);//此时的getVal1就是属性x的值
//也可以设置属性的值
Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(is1,3);
内省访问JavaBean有两种方法:
一、通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。(这种方法要麻烦一些)
二、通过PropertyDescriptor来操作Bean对象。(这种方法要简单得多)
接下来要对Student 类对象进行操作,Student类源码如下:
public class Student {
private String name;//字段
public String getXxx(){//读方法
return "xx";
}
public String setXxx(){//写方法
return "xx";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
首先、是第一种方式,源码如下:
public void test() throws Exception{
Student student = new Student();
//1.通过Introspector来获取bean对象的beaninfo
BeanInfo bif = Introspector.getBeanInfo(Student.class);
//2.通过beaninfo来获得属性描述器(propertyDescriptor)
PropertyDescriptor pds[] = bif.getPropertyDescriptors();
//3.通过属性描述器来获得对应的get/set方法
for(PropertyDescriptor pd:pds){
//4.获得并输出字段的名字
System.out.println(pd.getName());
//5.获得并输出字段的类型
System.out.println(pd.getPropertyType());
if(pd.getName().equals("name")){
//6.获得PropertyDescriptor对象的写方法
Method md = pd.getWriteMethod();
//7.执行写方法
md.invoke(student, "Lou_Wazor");
}
}
//8.输出所赋值字段的值
System.out.println(student.getName());
}
执行结果为:
class
class java.lang.Class
name
class java.lang.String
xxx
class java.lang.String
Lou_Wazor
以下是通过第二种方法来操作Bean对象,源码如下:
public void test01()throws Exception{
Student st = new Student();
//1.通过构造器来创建PropertyDescriptor对象
PropertyDescriptor pd = new PropertyDescriptor("name", Student.class);
//2.通过该对象来获得写方法
Method method = pd.getWriteMethod();
//3.执行写方法
method.invoke(st, "Lou_Wazor");
//4.输出对象字段的值
System.out.println(st.getName());
//5.通过对象获得读方法
method = pd.getReadMethod();
//6.执行读方法并定义变量接受其返回值并强制塑形
String name = (String) method.invoke(st, null);
//7.输出塑形后的值
System.out.println(name);
}
执行结果为:
Lou_Wazor
Lou_WazorJava中的JavaBean
一、JavaBean是什么?
JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean是一种特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。JavaBean可分为两种:一种是有用户界面(UI,User Interface)的JavaBean;还有一种是没有用户界面,主要负责处理事务(如数据运算,操纵数据库)的JavaBean。JSP通常访问的是后一种JavaBean。
/*** 一个简单的JavaBean
* @author JSON
*
*/
public class JavaBean {
/**
* 不写构造函数方法默认提供无参的构造函数方法,如果写了一个有参的构造函数方法,那 就有一个有参的构造函数方法,默认的无参构造函数方法就没有了----这是类的构
* 造方法的小知识与JavaBean没有什么关系的
*/// public JavaBean(){
//
// }
//私有属性
private int x;
//私有属性
private String y;
/**
* 得到属性值
* @return
*/
public int getX() {
return x;
}
/**
* 设置属性值
* @param x
*/
public void setX(int x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
}
二、用JavaBean的地方
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称为值对象(Value Object, VO),这些信息在类中用私有 字段来存储。JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量.如果方法名为setId,中文意思就是设置Id,至于你把它存到哪个变量上,不用考虑。如果方法名为getId,中文意思就是得到Id,至于你从哪个变量上取,不用考虑。去掉set前缀,剩余部分就是属性名,如果属性的第二个字母是小写的,那首字母小写,属性的第二个字母是大写的,首字母大写,大写是为了好看。
三、使用JavaBean要注意的地方
1.不要试图在JavaBean返回的HTML中放置任何字体尺寸。------并不是所有的浏览器都相同。很多浏览器无法处理完整的字体尺寸。
2.不要试图在JavaBean返回的HTML中放置任何脚本或者DHTML。------向页面直接输出脚本或者DHTML相当于自我毁灭,因为某些浏览器版本在处理不正确的脚本时会崩溃(非常少但是有)。如果用户的JavaBean在运行时是动态的推出复杂的HTML语言,用户将陷入调试的噩梦。另外,复杂的HTML将限制JavaBean的寿命和灵活性。
3.不要提供任何的选择。-----------如果用户使用不同的系统浏览页面,可以提供一种可以替换的方法。(关于这点我是不理解的)
四、JavaBean的特点
按着Sun公司的定义,JavaBean是一个可重复使用的软件组件。实际上JavaBean是一种Java类,通过封装属性和方法成为具有某种功能或者处理某个业务的对象,简称bean。由于javabean是基于java语言的,因此javabean不依赖平台,具有以下特点:
编写javabean就是编写一个java的类,所以你只要会写类就能编写一个bean,这个类创建的一个对象称做一个bean。为了能让使用这个bean的应用程序构建工具(比如JSP引擎)知道这个bean的属性和方法,只需在类的方法命名上遵守以下规则:
1. 如果类的成员变量的名字是xxx,那么为了更改或获取成员变量的值,即更改或获取属性,在类中可以使用两个方法:
关于JavaBean的更多详细可以去这里看http://baike.baidu.com/link?url=ufk07RHyoPK7W34El9WNQcA-UW1GtlpG1LedwwUoSdXHXrPaFgH-wiIvWKFPIqfv