java基础加强--JavaBean和内省Introspector
来源:互联网 发布:java实现登陆注册 编辑:程序博客网 时间:2024/06/15 10:18
内省(Introspector)是与反射有关的知识,主要对JavaBean进行操作。
那么什么是JavaBean?
JavaBean是一个特殊的Java类,这个特殊Java类里面的方法的名称符合某种约定的规则。
比如要获取一个对象上的age属性,获取age属性的方法名必须要写为getAge,并且getAge方法要有返回值。
设置age属性的方法名必须要为setAge,并且setAge方法没有返回值而且还要接收一个参数。
这些方法的前面要么set打头,要么get打头,这就叫符合某种特定的规则,符合这种特定规则的Java类就称为JavaBean
class Person{private int x;public int getAge() {return x;}public void setAge(int age) {this.x = age;}}
以普通Java类来看,这个类有个x名称的成员变量。
外部的人看不到类里面的私有变量,只能看得到你的公有方法,能看到你有个公有方法叫getAge(),他认为你有个age属性。
如果把一个Java类当中JavaBean来看的话,那么这个JavaBean的属性(而不是Java类的属性)
是根据getXXX和setXXX方法的名称来推断出来的。而不是内部的成员变量的名称。
如果把Person类当做一个JavaBean来看,它有一个age名称的属性,而不是x。
如果把Person当做JavaBean来操作的话,若要设置属性,设置的是age这个属性。不能说是设置x。因为我们根本就看不到x。
因此JavaBean的属性是根据方法名称来的。
------------------一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean!好处如下:
1、在Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地!
2、JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,怎么做,有一定难度吧?
用内省这套api操作JavaBean比用普通类的方式更方便。
------------------
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,大家觉得这些方法的名称叫什么好呢?JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你把它存到哪个变量上,用管吗?如果方法名为getId,中文意思即为获取id,至于你从哪个变量上取,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
setId()的属性名->id
isLast()的属性名->last
setCPU的属性名是什么?->CPU
getUPS的属性名是什么?->UPS
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
-----------------------
一个简单的JavaBean
public class Person { //这么一个类就可以称为javaBean; 用来封装数据的private String name; //字段对外提供了get或set方法。这个字段才能称之为属性。 /*一个Bean的属性不由它的字段决定,而由它的set或get方法决定 * 一个类有几个set或get方法它就有几个属性。 */private String password;private int age;/** * Object类里有个getClass方法。所以getClass也是Object的属性。 * 所有类都是从Object继承而来。所以getClass也Person的属性。 *//*public String getABC(){ //是属性,程序运行结果有ABC属性return null;}*/public void setABC(char age){//setABC()方法里要带有参数,不然ABC不是属性、程序运行结果没有ABC属性。}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;}}
-------------------
反射:一个类有多个组成部分,例如成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
为什么需要内省?(Introspector)
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套用于操作JavaBean的API,专门用于操作java对象的属性。
访问JavaBean属性的两种方式:
1、直接调用bean的setXXX或getXXX方法。
2、通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式。
(1)、通过PropertyDescriptor类操作Bean的属性。
(2)、通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
--------------------------
PropertyDescriptor属性描述器
public class PropertyDescriptor
- extends FeatureDescriptor
PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。
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 对象。Method
getReadMethod() 获得应该用于读取属性值的方法。
Method
getWriteMethod() 获得应该用于写入属性值的方法。
---------------------------
使用内省的方式对JavaBean进行操作:
需求:用内省的方式来读取JavaBean对象的x属性。
JavaBean:
public class Point {private int x;private int y;Point(int x,int y){this.x = x;this.y = 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;}}
IntrospectorTest:
import java.beans.PropertyDescriptor;import java.lang.reflect.Method;public class IntrospectorTest {public static void main(String[] args) throws Exception { Point p = new Point(3,4); String propertyName = "x"; //PropertyDescriptor构造方法的参数:第一个参数是属性名;第二个参数是要把哪一个Java类当中JavaBean来看 //从JavaBean身上获取属性,pd就代表了JavaBean的属性。 PropertyDescriptor pd = new PropertyDescriptor(propertyName, p.getClass()); //JavaBean的属性是由setXXX和getXXX组合出来的。既然得到了JavaBean的属性,那么进一步就可以得到属性背后的get和set方法 Method methodGetX = pd.getReadMethod();// getReadMethod是得到属性的只读的方法getXXX; Object retVal = methodGetX.invoke(p);//在p对象身上调用get方法,get方法不接收任何参数。 System.out.println(retVal); //3 //取出x的值还是原来反射的那一套,但是简便了很多 // 如果要把一个类当中JavaBean来操作,要取某个属性,一定是通过get方法来取。而要得到属性名对应的get方法是很麻烦的。"x"-->"X"-->"getX"-->methodGetX //而使用内省的API得到属性的get方法是很简单的,只要把JavaBean和属性名传进去就可以了。就会得到属性对应的get和set方法 Method methodSetX = pd.getWriteMethod();//getWriteMethod()是得到属性的只写的方法setXXX; methodSetX.invoke(p,7);//在p对象身上调用set方法,set方法接收一个参数。 retVal = methodGetX.invoke(p); System.out.println(retVal); //7 }}
-------------------
对JavaBean的复杂内省操作
内省的入口类(核心类)为:Introspector
public class Introspector
- extends Object
Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。
对于这三种信息,Introspector 将分别分析 bean 的类和超类,寻找显式或隐式信息,使用这些信息构建一个全面描述目标 bean 的 BeanInfo 对象。
static BeanInfo
getBeanInfo(Class<?> beanClass) 在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。
static BeanInfo
getBeanInfo(Class<?> beanClass, Class<?> stopClass) 在给定的“断”点之下,在 Java Bean 上进行内省,了解其所有属性和公开的方法。
getBeanInfo
public static BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException
- 在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。
如果 Java Bean 的 BeanInfo 类以前已经被内省,则从 BeanInfo 缓存中检索 BeanInfo 类。
- 参数:
beanClass
- 将要分析的 bean 类。- 返回:
- 描述目标 bean 的 BeanInfo 对象。
- 抛出:
IntrospectionException
- 如果在内省期间发生异常。- 另请参见:
flushCaches()
,flushFromCaches(java.lang.Class)
getBeanInfo
public static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass) throws IntrospectionException
- 在给定的“断”点之下,在 Java Bean 上进行内省,了解其所有属性和公开的方法。
如果 Java Bean 的 BeanInfo 类以前已经基于相同的参数被内省,则从 BeanInfo 缓存中检索 BeanInfo 类。
- 参数:
beanClass
- 将要分析的 bean 类。stopClass
- 从其所在位置开始停止分析的基类。stopClass 或其基类中的所有方法/属性/事件都将在分析中被忽略。- 抛出:
IntrospectionException
- 如果在内省期间发生异常。
用这个类到底Introspector 省谁?
可以调用它的getBeanInfo(beanClass)。给进去的bean是哪个就省谁。这个方法内部就会对这个Bean内省。省出来后就会把Bean的所有属性封装到一个BeanInfo的对象中(getBeanInfo方法负责返回BeanInfo接口的实例)。拿到这个对象就相当于拿到Bean的所有属性了。接着调用它的 getPropertyDescriptors() 方法就可以拿到每个属性的属性描述器(保存到PropertyDescriptor[] 数组中)。拿到描述器后就可以调用描述器的getReadMethod()方法(获得应该用于读取属性值的方法)得到属性的读方法即得到属性的get方法,就可以get这个属性的值。getWriteMethod()(获得应该用于写入属性值的方法)得到属性的写方法即得到属性的set方法,就可以往属性上设置值。
例子:
JavaBean:package com.congwiny.introspector;public class Person { //这么一个类就可以称为javaBean; 用来封装数据的private String name; //字段对外提供了get或set方法。这个字段才能称之为属性。 /*一个Bean的属性不由它的字段决定,而由它的set或get方法决定 * 一个类有几个set或get方法它就有几个属性。 */private String password;private int age;/** * Object类里有个getClass方法。所以getClass也是Object的属性。 * 所有类都是从Object继承而来。所以getClass也Person的属性。 *//*public String getABC(){ //是属性,程序运行结果有ABC属性return null;}*/public void setABC(char age){//setABC()方法里要带有参数,不然ABC不是属性、程序运行结果没有ABC属性。}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;}}
测试类Demo1:
package com.congwiny.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 { @Testpublic void test1() throws Exception{//得到所有的属性 //BeanInfo info = Introspector.getBeanInfo(Person.class);//得到bean自己的属性BeanInfo info = Introspector.getBeanInfo(Person.class,Object.class);//砍掉(stop掉)从父类Object继承的属性PropertyDescriptor[] pds = info.getPropertyDescriptors();//得到所有的属性描述for(PropertyDescriptor pd : pds){System.out.println(pd.getName()); //输出类Person所有属性的名字}}//操纵bean的指定属性:age@Testpublic void test2() throws Exception{Person p = new Person();PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);//得到属性的些方法,为属性赋值Method method = pd.getWriteMethod(); //public void setAge(int age) method.invoke(p, 45);//获取属性的值method = pd.getReadMethod();System.out.println(method.invoke(p, null));}//高级点内容:获取当前操作的属性的类型@Testpublic void test3() throws Exception{Person p = new Person();PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);System.out.println(pd.getPropertyType());}}
- java基础加强--JavaBean和内省Introspector
- java基础加强03 内省和JavaBean
- Java基础加强之内省(introspector)
- Java基础加强之内省(introspector)
- JavaBean和内省 IntroSpector
- 内省(introspector)和javabean
- JAVA内省JavaBean(Introspector、BeanInfo和PropertyDescriptor)
- 基础加强-IntroSpector(内省)
- java基础加强--内省与javaBean
- Java 基础加强 - JavaBean与内省操作
- 基础加强—04—内省(IntroSpector)
- Java高新技术之JavaBean(内省 IntroSpector)
- Java学习笔记-JavaBean-内省(Introspector)
- 【JavaEE】Java内省Introspector、PropertyDescriptor与JavaBean
- 【Java进阶】内省IntroSpector操作JavaBean和Apache-commons-dbutils对内省的使用
- 【内省】introspector操作JavaBean
- 内省IntroSpector与JavaBean
- 内省(Introspector) — JavaBean
- 利用VB2005制作颜色渐变的进度条
- 应用ExcelPackage导出Excel
- tarコマンドで解凍・圧縮するlinux一覧まとめ(gz、zipなど)
- 解决Sqlite Developer过期
- Common Intents
- java基础加强--JavaBean和内省Introspector
- VB.NET 2008窗体应用技巧
- 关于数组_1
- Machine Learning Foundation Lecture 04 Feasuibility of learning 学习笔记
- 计算机监控系统仿真开发平台的软件实现(上)
- Confluence 为图片,视频,音频和文档文件使用自动完成
- VB.NET实现关机和重新启动
- seo的核心和seo的境界杂谈
- 快照、索引库不一样浅谈以及其他