java基础加强之内省
java基础加强之内省
============================================================================= 内省(Introspector类) —> JavaBean ----------------------------------------------------------------------------- 一、为什么要学内省? 开发框架时,经常需要使用java对象的属性来封装程序的数据, 每次都使用 反射技术 完成此类操作过于麻烦,所以SUN公司开发了一套API,专门用于操作java对象的属性。 ----------------------------------------------------------------------------- 二、什么是JavaBean和属性的读写方法? bean就是类,javabean就是java类。 ----------------------------------------------------------------------------- 三、通过内省技术访问(java.beans包提供了内省的API)JavaBean的两种方式: 1、 通过 PropertyDescriptor类 操作 Bean 的属性 2、 通过 Introspector类 获得Bean对象的 BeanInfo,BeanInfo将一个类的所有属性进行了封装。 然后通过 BeanInfo对象 来获取属性的描述器对象 PropertyDescriptor, 通过这个属性描述器对象就可以获取某个属性对象,然后通过反射机制来调用getter/setter方法。 (注意:在反射里面,成员变量叫字段,成员方法(特指getter/setter方法)叫属性) PropertyDescriptor顾名思义,就是属性描述之意。它通过反射快速操作JavaBean的getter/setter方法。 重要方法: Method getWriteMethod() 获取setter方法,返回Method对像 Method getReadMethod() 获取getter方法,返回Method对像 -------------------------------------- Student stu = new Student(); // 得到指定的属性对象 PropertyDescriptor pd = new PropertyDescriptor("name", Student.class); Method setter = pd.getWriteMethod(); // 得到setter方法:setName() setter.invoke(stu, "tom"); Method getter = pd.getReadMethod(); // 得到getter方法:getName() System.out.println(getter.invoke(stu, null)); -------------------------------------- 看上面的代码思考一个问题:既然我已经实例化了Student类,为什么不直接调用它的setName方法呢? 其实正确的用法应该是:与Student类完全的解耦。(就是说我写的代码中不会出现学生类了,学生类放在配置文件里面) Class cls = Class.forName("cn.itcast.Student"); Object obj = cls.newInstance(); PropertyDescriptor pd = new PropertyDescriptor("name", cls); Method m = pd.getWriterMethod(); m.invode(obj, "tom"); m = pd.getReadMethod(); System.out.println((String) m.invoke(obj)); ----------------------------------------------------------------------------- 四、Beanutils工具包 Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景, 因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。 Beanutils工具包的常用类: BeanUtils PropertyUtils ConvertUtils.regsiter(Converter convert, Class clazz) 自定义转换器 -------------------------------------- 需要依赖两个jar包: commons-beanutils-1.8.3.jar commons-logging-1.1.1.jar -------------------------------------- 示例: Student stu = new Student(); BeanUtils.setProperty(stu, "name", "张三"); // 给属性赋值 String s = BeanUtils.getProperty(stu, "name"); // 获取属性值 System.out.println(s); -------------------------------------- Student stu = new Student(); BeanUtils.setProperty(stu, "age", "18"); // BeanUtils默认支持8种基本数据类型,自动转换 String s = BeanUtils.getProperty(stu, "age"); System.out.println(s); -------------------------------------- Student stu = new Student(); // 注册类型转换器 ConvertUtils.register(new DateLocaleConverter(), Date.class); BeanUtils.setProperty(stu, "birthday", "1990-11-12"); // 给属性赋值 String s = BeanUtils.getProperty(stu, "birthday"); System.out.println(s); -------------------------------------- Student stu = new Student(); // 注册类型转换器 ConvertUtils.register(new Converter() { @Override public Object convert(Class type, Object value) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); if (value instanceof String) { String v = (String) value; try { return sdf.parse(v); } catch (ParseException e) { throw new RuntimeException(e); } } return null; } }, Date.class); BeanUtils.setProperty(stu, "birthday", "1995-11-12"); // 给属性赋值 String s = BeanUtils.getProperty(stu, "birthday"); System.out.println(s); -------------------------------------- Map m = new HashMap(); m.put("name", "张三"); // key名一定要与对象中的变量名一致 m.put("age", "18"); // key名一定要与对象中的变量名一致 m.put("birthday", "1992-05-12"); // key名一定要与对象中的变量名一致 Student stu = new Student(); // 注册类型转换器 ConvertUtils.register(new DateLocaleConverter(), Date.class); BeanUtils.populate(stu, m); // 将Map属性自动填充Bean中,这句话,后期学到框架的时候经常用到 System.out.println(stu.getName()); =============================================================================
我的GitHub地址: https://github.com/heizemingjun
我的博客园地址: http://www.cnblogs.com/chenmingjun
我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun
Copyright ©2018 黑泽明军
【转载文章务必保留出处和署名,谢谢!】
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript 编程精解 中文第三版 三、函数
三、函数 原文:Functions 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2 版)》 人们认为计算机科学是天才的艺术,但是实际情况相反,只是许多人在其它人基础上做一些东西,就像一面由石子垒成的墙。 高德纳 函数是 JavaScript 编程的面包和黄油。 将一段程序包装成值的概念有很多用途。 它为我们提供了方法,用于构建更大程序,减少重复,将名称和子程序关联,以及将这些子程序相互隔离。 函数最明显的应用是定义新词汇。 用散文创造新词汇通常是不好的风格。 但在编程中,它是不可或缺的。 以英语为母语的典型成年人,大约有 2 万字的词汇量。 很少有编程语言内置了 2 万个命令。而且,可用的词汇的定义往往比人类语言更精确,因此灵活性更低。 因此,我们通常会引入新的概念,来避免过多重复。 定义函数 函数定义是一个常规绑定,其中绑定的值是一个函数。 例如,这段代码定义了square,来引用一个函数,它产生给定数字的平方: const square = function(x) { return x * x; }; con...
- 下一篇
leetcode算法题解(Java版)-5-简单模拟,字符串处理
一、简单贪心 题目描述 Given n non-negative integers a1 , a2 , ..., an , where each represents a point at coordinate (i, ai ). n vertical lines are drawn such that the two endpoints of line i is at (i, ai ) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. Note: You may not slant the container. 思路 这题在一分钟内就想了个笨方法,迅速敲完,KO! 因为题目还是很简单,不考虑将装水的容器倾斜,所以只要考虑梯形中最短的边和底边的乘积就行了:正反两遍循环数组,第一遍从0~len,先固定最左边的边,从右往左遍历数组,如果碰到大于等于最左边边长的边,那就判断是否大于当前的最大盛水体积...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Hadoop3单机部署,实现最简伪集群
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Docker使用Oracle官方镜像安装(12C,18C,19C)