java基础加强之内省

简介: java基础加强之内省=============================================================================内省(Introspector类) —> JavaBean ----------------------------...

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 黑泽明军
【转载文章务必保留出处和署名,谢谢!】
相关文章
|
存储 缓存 Java
最新Java基础系列课程--Day10-IO流文件处理
最新Java基础系列课程--Day10-IO流文件处理
134 2
|
存储 Java
最新Java基础系列课程--Day10-IO流文件处理(一)
最新Java基础系列课程--Day10-IO流文件处理
135 0
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
404 2
|
12月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
297 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
存储 安全 Java
Java内省(Introspector)机制:深入理解与应用
Java内省(Introspector)机制:深入理解与应用
|
搜索推荐 算法 Java
【Java基础】 几种简单的算法排序
几种简单的JAVA算法排序
108 4
Java基础教程(12)-Java中的IO流
【4月更文挑战第12天】Java IO涉及输入输出,包括从外部读取数据到内存(如文件、网络)和从内存输出到外部。流是信息传输的抽象,分为字节流和字符流。字节流处理二进制数据,如InputStream和OutputStream,而字符流处理Unicode字符,如Reader和Writer。File对象用于文件和目录操作,Path对象简化了路径处理。ZipInputStream和ZipOutputStream则用于读写zip文件。
119 2
|
存储 缓存 Java
Java基础17-读懂Java IO流和常见面试题(二)
Java基础17-读懂Java IO流和常见面试题(二)
117 0