黑马程序员技术交流社区

标题: 内省---操作javabean [打印本页]

作者: youxiao123    时间: 2017-10-29 16:55
标题: 内省---操作javabean
一.定义:
内省(Introspector)是java语言对JavaBean类属性/事件/方法的一种标准处理方方式。
这里需要注意:
[HTML] 纯文本查看 复制代码
<h1>内省与反射的区别</h1>

内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。不应该将内省和反射混淆。相对于内省,反射更进一步,是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力

二:内省访问JavaBean有两种方法:
       (1)通过java.beans包下Introspector类获得JavaBean对象的BeanInfo信息,再通过BeanInfo获得属性的描述器PropertyDescriptor类,在通过属性描述器就可以获取某个属性对应的getter和setter方法,最后使用反射来调用这些方法。
      (2)直接通过java.beans包下的PropertyDescriptor类来操作Bea对象。
代码例子:Person   bean类
[Java] 纯文本查看 复制代码
package com.itheima.bean;

public class Person {

        private String name;
        private int age;
        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 "Person [name=" + name + ", age=" + age + "]";
        }
}


内省操作类(Introsperctor)
[Java] 纯文本查看 复制代码
package com.itheima.introspector;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

import com.itheima.bean.Person;

public class IntrospectorDemo {
       
        public static void main(String[] args) throws IntrospectionException {
                //1.实例化一个Person
                Person beanObj = new Person();
               
                //2.依据Person产生一个相关的BeanInfo类
                BeanInfo infoObj = Introspector.getBeanInfo(beanObj.getClass(),
                                                                    beanObj.getClass().getSuperclass());
                String str="内省成员属性:\n";
               
                //3.获取该Bean中的所有属性的信息,以PropertyDescriptor数组的形式返回
                PropertyDescriptor[] propertyArray = infoObj.getPropertyDescriptors();
                for(int i=0;i<propertyArray.length;i++){
                        //获取属性名
                        String propertyName = propertyArray.getName();
                        //获取属性类型
                        Class propertyType = propertyArray.getPropertyType();
                       
                        str += propertyName+"("+propertyType.getName()+")\n";
                       
                }
                System.out.println(str);
        }

}



[HTML] 纯文本查看 复制代码
<h1>修改JavaBean的属性</h1>

package com.itheima.introspector;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.itheima.bean.Person;

/**
*
* 用PropertyDescriptor类来操作
*
* */

public class IntrospectorUpdate {
       
        public static void main(String[] args) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
               
                //创建Bean
                Person  p = new Person();
               
                //用属性描述器PropertyDescriptor类获取Person类name属性的描述信息
                PropertyDescriptor pd = new PropertyDescriptor("name",p.getClass());
               
                //获取name属性的getter方法是getReadMethod()
                //获取name属性对应的setter方法getWtriteMethod()
                Method methodName = pd.getWriteMethod();
                //利用反射来修改属性
                methodName.invoke(p,"小明");
               
                String val = "20";
            pd = new PropertyDescriptor("age",p.getClass());
                Method methodAge = pd.getWriteMethod();
                //获取属性的java类型
                Class clazz = pd.getPropertyType();
                //根据类型来判断需要为setter方法传入什么类型的实参
                if(clazz.equals(int.class)){
                        methodAge.invoke(p, Integer.valueOf(val));
                }else{
                        methodAge.invoke(pd, val);
                }
                //注意:在使用内省设置属性值的时候,必须要设置对应数据类型的数据,否则会报错。
                System.out.println(p);
               
        }

}

最近学的struts中有用到Intropector哦:
Web 开发框架 Struts 中的 FormBean 就是通过内省机制来将表单中的数据映射到类的属性上,因此要求 FormBean 的每个属性要有 getter/setter 方法。但也并不总是这样,什么意思呢?就是说对一个 Bean 类来讲,我可以没有属性,但是只要有 getter/setter 方法中的其中一个,那么 Java 的内省机制就会认为存在一个属性,比如类中有方法 setMobile ,那么就认为存在一个 mobile 的属性。

将 Java 的反射以及内省应用到程序设计中去可以大大的提供程序的智能化和可扩展性。有很多项目都是采取这两种技术来实现其核心功能,例如我们前面提到的 Struts ,还有用于处理 XML 文件的 Digester 项目,其实应该说几乎所有的项目都或多或少的采用这两种技术。在实际应用过程中二者要相互结合方能发挥真正的智能化以及高度可扩展性。

作者: youxiao123    时间: 2017-10-29 16:57

作者: 太阿    时间: 2017-10-30 20:54
反正不懂,加油gogogogo
作者: 小皖妹妹    时间: 2017-10-31 15:53
见贤思齐,见不贤而内自省也
作者: 马叉虫    时间: 2017-10-31 19:04
{:8_468:}这个排版.....似曾相识
作者: Timer    时间: 2017-10-31 19:29
有效55555
作者: hguilin    时间: 2017-10-31 23:15
66

作者: 黑马啸西风    时间: 2017-11-1 09:41
666666
作者: hguilin    时间: 2017-11-7 17:13

作者: 皖哥哥    时间: 2017-11-7 18:51
再来个大总结,点点睛就更棒了
作者: zhounan99    时间: 2017-11-8 19:18
对于反射 我一窍不通
作者: 你骄哥!    时间: 2017-11-8 19:27
骄哥发来贺电
作者: 萌动天辰    时间: 2017-11-13 20:16
同桌的我前来报到




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2