A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘肥 黑马帝   /  2011-9-16 13:47  /  2888 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

JavaBean中直接调用get与set方法不就行了,为什么要弄一个内省,这么麻烦。

评分

参与人数 1技术分 +1 收起 理由
wangfayin + 1

查看全部评分

9 个回复

倒序浏览
黑马网友  发表于 2011-9-16 13:51:49
沙发
内省(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 方法,然后我们就可以通过反射机制来调用这些方法。

我们又通常把javabean的实例对象称之为值对象(Value Object),因为这些bean中通常只有一些信息字段和存储方法,没有功能性方法。

一个JavaBean类可以不当JavaBean用,而当成普通类用。JavaBean实际就是一种规范,当一个类满足这个规范,这个类就能被其它特定的类调用。一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。去掉set前缀,然后取剩余部分,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。下面就用前面的讲解的反射方式来设置或读取JavaBean的属性:
        import java.beans.BeanInfo;
        import java.beans.IntrospectionException;
        import java.beans.Introspector;
        import java.beans.PropertyDescriptor;
    除了反射用到的类需要引入外,内省需要引入的类如上所示,它们都属于java.beans包中的类,自己写程序的时候也不能忘了引入相应的包或者类。下面代码片断是一个设置某个JavaBean类某个属性的关键代码:
        private static void setObjectProperty(ReflectPoint pt1, int value,String propName) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
            /*BeanInfo bean = Introspector.getBeanInfo(ReflectPoint.class);
            PropertyDescriptor [] properties = bean.getPropertyDescriptors();
            for(PropertyDescriptor property: properties)
            {
                if(property.getName().equals(propName))
                {
                    Method mSetX = property.getWriteMethod();
                    mSetX.invoke(pt1, value);
                    break;
                }
            }*/
            PropertyDescriptor property = new PropertyDescriptor("x",ReflectPoint.class);
            Method mSetX = property.getWriteMethod();
            mSetX.invoke(pt1, value);
        }
    代码中注释的语句代表一种方式,最后的三行代表另外一种设置相应类相应属性的方式。从简洁上来说,第二种方式显然更优雅。第一种方式中首先是获得相应javaBean的类信息bean,用的BeanInfo这个类来描述的。然后就能够通过getPropertyDescriptors方法获取属性描述数组对象。最后从数组中取去一个个的属性对象进行操作——获取相应的读写方法,然后调用相应的读写方法。这些是通过反射机制做到的。由于这种方式比较麻烦,如果只调用其中一种方法,就要遍历一次属性描述数组,所以就产生了第二种方式,直接通过传入属性名称,相应的javaBean类型参数,构造出一个需要的PropertyDescriptor对象,然后再进行调用。
    理解了相应的原理,那些现成的工具用起来就会更舒服,如Beanutils与PropertyUtils工具。这两个工具设置属性的时候一个主要区别是PropertyUtils.getPropety方法获得的属性值的类型为该属性本来的类型,而BeanUtils.getProperty则是将该属性的值转换成字符串后才返回。

评分

参与人数 1技术分 +3 收起 理由
wangfayin + 3 回答的非常好!

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-9-16 13:57:59
藤椅

回复 沙发 的帖子

你把自己笔记贴过来了?
回复 使用道具 举报
黑马网友  发表于 2011-9-16 14:06:39
板凳
有帮助吗?呵呵
回复 使用道具 举报
黑马网友  发表于 2011-9-16 14:33:42
报纸
呵呵,因为我们做WEB开发需要用到框架,现在流行的MVC框架开发就要用到JAVABeans,框架对此一般通过代理用反射进行调用,所以内省是很有必要的。
回复 使用道具 举报
黑马网友  发表于 2011-9-16 16:40:50
地板

回复 板凳 的帖子

感觉你写的挺好的,总结也挺好,比我写的好。
有深度:loveliness:
回复 使用道具 举报
黑马网友  发表于 2011-9-16 17:08:58
7#
=- = 可惜我发了1天的回帖 1分莫有啊  哭啊
回复 使用道具 举报
黑马网友  发表于 2011-9-17 01:12:06
8#

回复 7 # 的帖子

别哭啊!我来晚了……:(
回复 使用道具 举报
黑马网友  发表于 2011-9-17 01:40:06
9#
我想问下内省是什么意思==我只知道就是这是简单化的反射
回复 使用道具 举报
724681149 黑马帝 2011-10-15 01:55:18
10#
厉害,占用整个篇幅。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马