------- android培训、java培训、期待与您交流! ----------
29.由内省引出JavaBean的讲解
1.内省对应的英文单词是IntroSpector,它主要用于对JavaBean进行操作。
2.了解JavaBean
1)JavaBean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的
字段,且方法名符合某种命名规则。
2)如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象
通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,用set()和get()
方法来设置和获取。
3)通过提供的set和get方法就知道属性名,一个类被当作JavaBean使用时,JavaBean的属性是根据方法名
推断出来的,它根本看不到java类内部的成员变量。
如果第二个字母是小写的,则把第一个字母变成小写的:
gettime-->time
setTime-->time
getCPU-->CPU
4)一个符合JavaBean特点的类可以当作普通类进行使用,但当作JavaBean用会有额外的好处。
30.对JavaBean的简单内省操作
1.eclipse使用技巧
1)生成get和set方法
右键-->Source-->Generate Getters and Setters -->勾选x,y -->OK
2)抽取方法:
选中代码-->右键-->Refactor-->Extract Method -->输入方法名:eg:getProperty
2.PropertyDescriptor(java.beans 包)属性描述类
1)public class PropertyDescriptor
extends FeatureDescriptor
PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。
2)构造方法摘要
PropertyDescriptor(String propertyName, Class<?> beanClass)
通过调用 getFoo 和 setFoo 存取方法,为符合标准 Java 约定的属性构造一个 PropertyDescriptor。
PropertyDescriptor(String propertyName, Class<?> beanClass, String readMethodName, String writeMethodName)
此构造方法带有一个简单属性的名称和用于读写属性的方法名称。
PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod)
此构造方法带有某一简单属性的名称,以及用来读取和写入属性的 Method 对象。
3)方法摘要
Class<?> getPropertyType()
获得属性的 Class 对象。
Method getReadMethod()
获得应该用于读取属性值的方法。
Method getWriteMethod()
获得应该用于写入属性值的方法。
void setReadMethod(Method readMethod)
设置应该用于读取属性值的方法。
void setWriteMethod(Method writeMethod)
设置应该用于写入属性值的方法。
。
3.类 FeatureDescriptor(java.beans包)
1)public class FeatureDescriptor
extends Object
FeatureDescriptor 类是 PropertyDescriptor、EventSetDescriptor 和 MethodDescriptor 等的公共基类。
它支持一些可以设置和检索任意的内省描述符的公共信息。
此外,它还提供了一种扩展机制,从而任意属性/值对都可以与设计特性相关联。
2)构造方法摘要
FeatureDescriptor()
构造一个 FeatureDescriptor。
3)方法摘要
String getName()
获得此特性的编程名称。
Object getValue(String attributeName)
利用此特性检索指定属性。
void setName(String name)
设置此特性的编程名称。
void setValue(String attributeName, Object value)
将某一指定属性与此特性相关联。
class ReflectPoint2
{
private int x;
private int y;
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 ReflectPoint2(int x, int y) {
this.x = x;
this.y = y;
}
}
31.对JavaBean的复杂内省操作
1.接口 BeanInfo(java.beans 包)
1)public interface BeanInfo希望提供有关其 bean 的显式信息的 bean 实现者可以提供某个 BeanInfo 类,
该类实现此 BeanInfo 接口并提供有关其 bean 的方法、属性、事件等显式信息。
请参见 SimpleBeanInfo 类,它提供了用于 BeanInfo 类的一个便捷 "noop" 基类,
可以为那些想要返回显式信息的特定位置重写该基类。
2)方法摘要
MethodDescriptor[] getMethodDescriptors()
获得 beans MethodDescriptor。
PropertyDescriptor[] getPropertyDescriptors()
获得 beans PropertyDescriptor。
2.类 Introspector(java.beans)
1)public class Introspectorextends Object
Introspector 类为通过工具学习有关受目标 Java Bean
支持的属性、事件和方法的知识提供了一个标准方法。
对于这三种信息,Introspector 将分别分析 bean 的类和超类,寻找显式或隐式信息,
使用这些信息构建一个全面描述目标 bean 的 BeanInfo 对象。
2)方法摘要
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 上进行内省,了解其所有属性、公开的方法和事件,并将结果用一些控制标记表示。
/*JavaBean是一个特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法名负荷某种命名规则
* IntroSpector-->JavaBean-->特殊的Java类
* Age-->如果第二个字母是小的,则把第一个字母变成小的-->age 就为了好看
* gettime-->time
* setTime-->time
* getCPU-->CPU
* 一个类被当作JavaBean使用时,JavaBeam的属性是根据方法名推断出来,它根本看不到java类内部的成员变量
*/
public class a29_由内省引出JavaBean的讲解 {
public static void main(String[] args) throws Exception {
ReflectPoint2 pt1 = new ReflectPoint2(3,5);
String propertyName="x";
//"x"-->"X"-->"getX"-->MethodGetX
Object retVal = getProperty(pt1, propertyName);
System.out.println(retVal);
//提取方法A+S+M
Object value=7;
setProperty(pt1, propertyName, value);
System.out.println(pt1.getX());
//使用BeanUtils工具包 只能使用public类
System.out.println(BeanUtils.getProperty(pt1, "x"));
BeanUtils.setProperty(pt1, "x", "9");
System.out.println(pt1.getX());
}
//通过内省,设置x属性的值
private static void setProperty(ReflectPoint2 pt1, String propertyName,
Object value) throws Exception{
//通过属性名,获取该对象rp下该属性x的属性描述器
PropertyDescriptor pd2=new PropertyDescriptor(propertyName,pt1.getClass());
//通过属性描述器,获取该属性x的读方法,即getter方法
Method methodSetX= pd2.getWriteMethod();
//利用反射调用该setter方法,设置属性x的值
methodSetX.invoke(pt1, value);
}
//通过内省,获取x属性的值
private static Object getProperty(Object pt1, String propertyName)
throws Exception {
PropertyDescriptor pd=new PropertyDescriptor(propertyName,pt1.getClass());
//通过属性描述器,获取该属性x的写方法,即setter方法
Method methodGetX= pd.getReadMethod();
Object retVal=methodGetX.invoke(pt1);
return retVal;
}
}
//通过内省,获取x属性的值 复杂操作
private static Object getProperty(Object pt1, String propertyName)
throws Exception {
Object retVal=null;
//获取该JavaBean类的beanInfo,它存储了该JavaBean的所有属性信息
BeanInfo beanInfo=Introspector.getBeanInfo(pt1.getClass());
//获取该JavaBean类的所有属性描述器
PropertyDescriptor[] pds= beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if( pd.getName().equals(propertyName))//判断是否x属性的描述器
{
Method methodGetX=pd.getReadMethod();
retVal=methodGetX.invoke(pt1);
break;
}
}
return retVal;
}
}
32.使用BeanUtils工具包操作JavaBean
1.下载BeanUtils工具包(以jar包形式存在)
下载commons-beanutils-current.zip-->解压-->查看API-->查看README.txt(可放在编辑器中查看)
2.安装jar包
工程上右键-->New-->Folder-->输入名称:lib-->将commons-beanutils.jar 拷贝到lib中
-->在该jar包上右击-->Build Path-->Add to Build Path(此时该jar包变成了一个小奶瓶的形状)
注意:在没有将jar包拷到工程中的lib中以前,不可以直接工程右击-->Build Path --> configure-->
Build Path -->Add External JARS(增加外部的项)
因为这样的话,jar包还在电脑上,而不在工程当中,此时发给别人用的时候,别人就找不到该jar包。
3.报错:System.out.println(BeanUtils.getProperty(pt1,"x");代码报错:NoClassDefFoundError
原因是缺少logging日志开发包。
4.下载commos-logging-1.1-ide.zip以同样的道理,解压,拷到lib中,再增加到工程当中。
5.java7的新特性:
Map map = {name:"lisi",age:18};
BeanUtils.setProperty(map,"name","zhangsan");
6.PropertyUtils和BeanUtils的区别;
BeanUtils接收返回的都是String类型,可自动完成属性的类型转换。
PropertyUtils是以属性本身的类型进行操作。
public class IntrospectorTest {
public static void main(String[] args) throws Exception{
ReflectPoint rp=new ReflectPoint(3, 5);
String propertyName="x";
//利用Beanutils工具包操作JavaBean类
System.out.println(BeanUtils.getProperty(rp, propertyName));//直接获取某个对象的某个属性的值,类似例1中重构后的方法
BeanUtils.setProperty(rp, propertyName,"9");//直接设置某个对象的某个属性的值,类似例1中重构后的方法,但注意其接收的值类型为Object,常用String类型,更符合开发实际需求
System.out.println(rp.getX());
System.out.println(BeanUtils.getProperty(rp, propertyName).getClass().getName());//说明该方法返回值为String类型,比例1中重构后的方法更符合开发实际需求
//支持对属性链的连续调用
BeanUtils.setProperty(rp, "birthday.time", "111");
System.out.println(BeanUtils.getProperty(rp, "birthday.time"));
//get方法返回该属性本来的类型,set方法只接受该属性本类的类型
PropertyUtils.setProperty(rp, propertyName, 12);
System.out.println(rp.getX());
}
}