您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
javase第三季学习笔记-内省机制
发布时间:2017-08-10 15:18:48编辑:雪饮阅读()
JavaBean的概念
• 什么是 JavaBean?
• Bean理解为组件意思, JavaBean就是Java组件,在广泛的理解就是一个类,对于组件来说,关键在于要具有“能够被IDE构建工具侦测其属性和事件”的能力,通常在Java中。
• 一个JavaBean要具备这样的命名规则:
• 1、对于一个名称为xxx的属性,通常你要写两个方法:getXxx()和setXxx()。任何浏 览这些方法的工具,都会把get或set后面的第一个字母自动转换为小写。
• 2、对于布尔型属性,可以使用以上get和set的方式,不过也可以把get替换成is。
• 3、Bean的普通方法不必遵循以上的命名规则,不过它们必须是public的。
• 4、对于事件,要使用Swing中处理监听器的方式。如addWindowListener, removeWindowListener
内省基本概念
• 内省(IntroSpector)是Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。
• 通过 getName/setName 来访问 name 属性,这就是默认的规则。
• Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则,这些 API 存放于包 java.beans 中,一般的做法是通过类 Introspector 的 getBeanInfo方法 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。
Introspector 相关API
1、Introspector类:
Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。
static BeanInfo getBeanInfo(Class<?> beanClass)
在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。
2、BeanInfo类:
该类实现此 BeanInfo 接口并提供有关其 bean 的方法、属性、事件等显式信息。
MethodDescriptor[] getMethodDescriptors()
获得 beans MethodDescriptor。
PropertyDescriptor[] getPropertyDescriptors()
获得 beans PropertyDescriptor。
Properties 属性文件工具类的使用
3、PropertyDescriptor 类:
PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。
Method getReadMethod()
获得应该用于读取属性值的方法。
Method getWriteMethod()
获得应该用于写入属性值的方法。
4、MethodDescriptor 类:
MethodDescriptor 描述了一种特殊方法,
即 Java Bean 支持从其他组件对其进行外部访问。
Method getMethod()
获得此 MethodDescriptor 封装的方法。
示例代码:
入口程序:
package com.vince.introspector;
//内省
public class IntrospectorDemo {
public static void main(String[] args) {
Dog dog=DogFactory.getDog("dog");
System.out.println(dog);
}
}
javaBean:
package com.vince.introspector;
//javaBean
public class Dog {
private String name;
private int age;
public Dog(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Dog() {
super();
}
public static void main(String[] args) {
}
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;
}
@Override
public String toString() {
return "Dog [name=" + name + ", age=" + age + "]";
}
}
工厂类:
package com.vince.introspector;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
//工厂类
public class DogFactory {
//属性文件操作类
private static Properties config=new Properties();
static{
//读取属性文件,至于路径为什么是bean.properties因为bean.properties放在src下而非包下,若在包下则是com.vince.introspector. bean.properties的路径格式
InputStream inStream=Thread.currentThread().getContextClassLoader().getResourceAsStream("bean.properties");
//加载属性文件
try {
config.load(inStream);
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Dog getDog(String name){
//从Properties对象中根据key获取value
String className = config.getProperty(name);
try {
//根据类全名获取类信息对象(Class对象)
Class dogClass=Class.forName(className);
//实例化对象
Dog dog=(Dog)dogClass.newInstance();
//内省(获取bean信息)
BeanInfo beanInfo=Introspector.getBeanInfo(dogClass);
//通过bean信息获取所有属性描述器,数组
PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
for(int i=0;i<pds.length;i++){
if("name".equals(pds[i].getName())){
String nameValue=config.getProperty("dog.name");
//通过属性描述器获取该属性的写操作方法(set方法)
Method method=pds[i].getWriteMethod();
//在dog对象上调用方法
method.invoke(dog, nameValue);
}
else if("age".equals(pds[i].getName())){
String ageValue=config.getProperty("dog.age");
Method method=pds[i].getWriteMethod();
method.invoke(dog, Integer.parseInt(ageValue));
}
}
return dog;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
配置文件:
建立配置文件:
填写完整文件名:
编辑文件内容:
#配置javabean的全名
dog=com.vince.introspector.Dog
dog.name=\u5c0f\u767d
dog.age=3
文件内容中dog.name字段值为unicode值,为了防止即便是utf8保存本配置文件仍然会在入口程序输出时出现乱码。
jdk目录下native2ascii.exe可将字符转换为unicode编码
直接运行该工具,然后会出现cmd控制台,直接输入你的字符,然后按回车即可获得unicode值。
文件保存时可能会报错,我们直接选择utf-8
或者设置以下地方为utf-8:
关键字词:javase,内省机制