java内省

在类Person中有属性name,那么我们可以通过getName()和setName()来得到其值或者设置新的值,通过 getName()和setName()来访问name属性,这就是我们以前常用的方式。为了让程序员更好地操作JavaBean的属性,JDK中提供了一套 API 用来访问某个属性的getter和setter方法,这就是内省。内省(Introspector) 是Java 语言对 JavaBean 类属性、事件和方法的一种标准处理方式,它的出现有利于操作对象属性,并且可以有效地减少代码量。

内省访问JavaBean有两种方法,具体如下:

●先通过java.beans包下的Introspector类获得JavaBean对象的BeanInfo信息,再通过BeanInfo来获取属性的描述器(PropertyDescriptor),然后通过这个属性描述器就可以获取某个属性对应的 getter和setter方法,最后通过反射机制来调用这些方法。

● 直接通过java.beans包下的PropertyDescriptor类来操作Bean对象。

为了让大家更好地了解什么是内省,接下来通过一个案例来演示内省如何获得JavaBean中的所有属性和方法。在演示内省操作前需要首先定义一个JavaBean,在chapter08工程的cn.itcast.chapter08.javabean包下定义Person类,如例1所示。

例1 Person.java

 1    package cn.itcast.chapter08.javabean;
 2    public class Person {
 3        private String name; // 定义属性name,表示姓名
 4        private int age;     // 定义属性age,表示年龄
 5        public String getName() {
 6            return name;
 7        }
 8        public void setName(String name) { // 设置name属性
 9            this.name = name;
 10        }
 11        public int getAge() {
 12            return age;
 13        }
 14        public void setAge(int age) { // 设置name属性
 15            this.age = age;
 16        }
 17        //重写toString()方法
 18        public String toString() {
 19            return "姓名:"+this.name+",年龄:"+this.age;
 20        }
 21    }

然后针对上面的JavaBean来演示具体的内省操作,如例2所示。

例2 IntrospectorDemo01.java

 1    package cn.itcast.chapter08.introspector;
 2    import java.beans.BeanInfo;
 3    import java.beans.Introspector;
 4    import java.beans.PropertyDescriptor;
 5    import cn.itcast.chapter08.javabean.Person;
 6    public class IntrospectorDemo01 {
 7        public static void main(String[] args) throws Exception {
 8            //实例化一个Person对象
 9            Person beanObj = new Person();
 10            //依据Person产生一个相关的BeanInfo类
 11            BeanInfo bInfoObject = Introspector.getBeanInfo(beanObj.getClass(),
 12                    beanObj.getClass().getSuperclass());
 13            String str = "内省成员属性:\n";
 14            //获取该Bean中的所有属性的信息,以PropertyDescriptor数组的形式返回
 15            PropertyDescriptor[] mPropertyArray = bInfoObject
 16                    .getPropertyDescriptors();
 17            for (int i = 0; i < mPropertyArray.length; i++) {
 18                //获取属性名
 19                String propertyName = mPropertyArray[i].getName();
 20                //获取属性类型
 21                Class propertyType = mPropertyArray[i].getPropertyType();
 22                //组合成“属性名 (属性的数据类型)”的格式
 23                str += propertyName + " ( " + propertyType.getName() + " )\n";
 24            }
 25            System.out.println(str);
 26        }
 27    }

运行结果如图1所示。

图1 运行结果

在例2中,第9行代码用于创建Person类的对象,第11~12行代码通过内省调用getBeanInfo()方法,获取Person类对象的BeanInfo信息,第15~16行代码通过BeanInfo获取属性的描述器,第17~24行代码遍历获取每个属性的属性信息。

修改JavaBean的属性

在Java中,还可以使用内省修改JavaBean的属性。为了让读者更好地掌握如何使用内省修改JavaBean的属性,接下来通过一个案例来演示,如例1所示。

例1 IntrospectorDemo02.java

 1    package cn.itcast.chapter08.introspector;
 2    import java.beans.PropertyDescriptor;
 3    import java.lang.reflect.Method;
 4    import cn.itcast.chapter08.javabean.Person;
 5    public class IntrospectorDemo02 {
 6        public static void main(String[] args) throws Exception {
 7            //创建Person类的对象
 8            Person p = new Person();
 9            //使用属性描述器获取Person类name属性的描述信息
 10            PropertyDescriptor pd = new PropertyDescriptor("name",p.getClass());
 11            //获取name属性对应的setter方法
 12            Method methodName = pd.getWriteMethod();
 13            //调用setter方法,并设置(修改)name属性值
 14            methodName.invoke(p, "小明");
 15            //String类型的数据,表示年龄
 16            String val = "20";
 17            //使用属性描述器获取Person类age属性的描述信息
 18            pd = new PropertyDescriptor("age",p.getClass());
 19            //获取age属性对应的setter方法
 20            Method methodAge = pd.getWriteMethod();
 21            //获取属性的Java数据类型
 22            Class clazz = pd.getPropertyType();
 23            //根据类型来判断需要为setter方法传入什么类型的实参
 24            if(clazz.equals(int.class)){
 25                //调用setter方法,并设置(修改)age属性值
 26                methodAge.invoke(p, Integer.valueOf(val));
 27            }else{
 28                methodAge.invoke(p, val);
 29            }
 30            System.out.println(p);
 31        }
 32    }

运行结果如图1所示。

图1 运行结果

在例1中,第10行代码通过PropertyDescriptor描述器获取Person类中name属性的描述信息,第12行代码用于获取name属性的setter方法,第14行代码调用setter方法并传入实参,第22~29行代码用于获取age属性的数据类型,然后根据类型来判断为setter传入什么类型的实参。需要注意的是,使用内省设置属性的值时,必须要设置对应数据类型的数据,否则程序会出错。

读取JavaBean的属性 

 

通过前面小节的学习知道,Java的内省可以修改JavaBean的属性,使用PropertyDescriptor类的getWriteMethod()方法就可以获取属性对应的setter方法。在JavaBean中,属性的getter和setter方法是成对出现的,因此Java的内省也提供了读取JavaBean属性的方法,只要使用PropertyDescriptor类的getReadMethod()方法即可。

为了让读者更好地掌握通过内省如何读取JavaBean的属性,接下来通过一个案例来演示,如例1所示。

例1 IntrospectorDemo03.java

 1    package cn.itcast.chapter08.introspector;
 2    import java.beans.PropertyDescriptor;
 3    import java.lang.reflect.Method;
 4    import cn.itcast.chapter08.javabean.Person;
 5    public class IntrospectorDemo03 {
 6        public static void main(String[] args) throws Exception {
 7            //创建Person类的对象
 8            Person p = new Person();
 9            //通过直接调用setter方法的方式为属性赋值
 10            p.setName("李芳");
 11            p.setAge(18);
 12            //使用属性描述器获取Person类name属性的描述信息
 13            PropertyDescriptor pd = new PropertyDescriptor("name",p.getClass());
 14            //获取name属性对应的getter方法
 15            Method methodName = pd.getReadMethod();
 16            //调用getter方法,并获取name属性值
 17            Object o = methodName.invoke(p);
 18            System.out.println("姓名:"+o);
 19            //使用属性描述器获取Person类age属性的描述信息
 20            pd = new PropertyDescriptor("age",p.getClass());
 21            //获取name属性对应的setter方法
 22            Method methodAge = pd.getReadMethod();
 23            //调用getter方法,并获取age属性值
 24            o = methodAge.invoke(p);
 25            System.out.println("年龄:"+o);
 26        }
 27    }

运行结果如图1所示。

图1 运行结果

在例1中,首先创建Person类的实例,再通过实例调用setter方法直接为属性赋值,然后通过内省读取设置后的属性值。第17行代码用于获取Person类中的name属性的描述信息,第22行代码通过调用getReadMethod()方法获取name属性的getter方法,第24行代码调用getter方法,并获取name属性值。

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值