zoukankan      html  css  js  c++  java
  • Java内省详解

      内省和反射有什么区别:

      反射式在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。 
      内省机制是通过反射来实现的,BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性。

      1.通过PropertyDescriptor修改属性方式

     1 public class BeanInfoUtil {  
     2     public static void setProperty(UserInfo userInfo,String userName)throws Exception{  
     3         PropertyDescriptor propDesc=new PropertyDescriptor(userName,UserInfo.class);  
     4         Method methodSetUserName=propDesc.getWriteMethod();  
     5         methodSetUserName.invoke(userInfo, "wong");  
     6         System.out.println("set userName:"+userInfo.getUserName());  
     7     }  
     8 
     9     public static void getProperty(UserInfo userInfo,String userName)throws Exception{  
    10         PropertyDescriptor proDescriptor =new PropertyDescriptor(userName,UserInfo.class);  
    11         Method methodGetUserName=proDescriptor.getReadMethod();  
    12         Object objUserName=methodGetUserName.invoke(userInfo);  
    13         System.out.println("get userName:"+objUserName.toString());  
    14     }  
    15 
    16 }  

      2.通过Introspector类修改属性

     1 public class BeanInfoUtil2 {  
     2     public static void setPropertyByIntrospector(UserInfo userInfo,  
     3             String userName) throws Exception {  
     4 
     5         BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
     6         PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
     7         if (proDescrtptors != null && proDescrtptors.length > 0) {  
     8             for (PropertyDescriptor propDesc : proDescrtptors) {  
     9                 if (propDesc.getName().equals(userName)) {  
    10                     Method methodSetUserName = propDesc.getWriteMethod();  
    11                     methodSetUserName.invoke(userInfo, "alan");  
    12                     System.out  
    13                             .println("set userName:" + userInfo.getUserName());  
    14                     break;  
    15                 }  
    16             }  
    17         }  
    18     }  
    19 
    20     public static void getPropertyByIntrospector(UserInfo userInfo,  
    21             String userName) throws Exception {  
    22         BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
    23         PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
    24         if (proDescrtptors != null && proDescrtptors.length > 0) {  
    25             for (PropertyDescriptor propDesc : proDescrtptors) {  
    26                 if (propDesc.getName().equals(userName)) {  
    27                     Method methodGetUserName = propDesc.getReadMethod();  
    28                     Object objUserName = methodGetUserName.invoke(userInfo);  
    29                     System.out  
    30                             .println("get userName:" + objUserName.toString());  
    31                     break;  
    32                 }  
    33             }  
    34         }  
    35     }  
    36 
    37 }  

      注意事项,在上述修改JavaBean属性的时候,如果数据类型不对的话,会报错。例如BeanInfoUtil.setProperty(userInfo, “age”);报错是应为age属性是int数据类型,而setProperty方法里面默认给age属性赋的值是String类型。所以会爆出argument type mismatch参数类型不匹配的错误信息。 
      为了解决上述问题,Apache开发了一套简单、易用的API来操作Bean的属性——BeanUtils工具包。 

      

    public static void main(String[] args) throws Exception {     
            Point point = new Point(2, 5);     
            String proName = "x";     
            BeanUtils.setProperty(point, proName, "8");     
            System.out.println(point.getX());// 8     
            System.out.println(BeanUtils.getProperty(point, proName));// 8     
            System.out.println(BeanUtils.getProperty(point, proName).getClass().getName());// java.lang.String     
            
            BeanUtils.setProperty(point, proName, 8);     
           System.out.println(BeanUtils.getProperty(point, proName).getClass().getName());// java.lang.String     
       }     
       //我们看到虽然属性x的类型是Integer,但是我们设置的时候无论是Integer还是String,BeanUtils的内部都是当成String来处理的。  

      BeanUtils支持javabean属性的级联操作;

     1 public static void main(String[] args) throws Exception {     
     2     Point point = new Point(2, 5);//在point中加一个属性 private Date birth = new Date();并产生setter/getter方法     
     3     String proName = "birth";     
     4     Date date= new Date();     
     5     date.setTime(10000);     
     6     BeanUtils.setProperty(point, proName, date);     
     7     System.out.println(BeanUtils.getProperty(point, proName));     
     8          
     9     BeanUtils.setProperty(point, "birth.time", 10000);     
    10     System.out.println(BeanUtils.getProperty(point, "birth.time"));//10000     
    11 }     
    12 //之所以可以 BeanUtils.setProperty(point, "birth.time", 10000);这样写,那是因为Date类中有getTime()和setTime()方法,即Date类中相当于有time这个属性。   

      BeanUtils和PropertyUtils对比:

     1 public static void main(String[] args) throws Exception {     
     2     Point point = new Point(2, 5);     
     3     String proName = "x";     
     4     BeanUtils.setProperty(point, proName, "8");     
     5     System.out.println(BeanUtils.getProperty(point, proName));//8     
     6     System.out.println(BeanUtils.getProperty(point, proName).getClass().getName());//java.lang.String     
     7          
     8 // PropertyUtils.setProperty(point, proName, "8");//exception:argument type mismatch     
     9     PropertyUtils.setProperty(point, proName, 8);     
    10     System.out.println(PropertyUtils.getProperty(point, proName));//8     
    11     System.out.println(PropertyUtils.getProperty(point, proName).getClass().getName());//java.lang.Integer     
    12 }     
    13 //BeanUtils它以字符串的形式对javabean进行转换,而PropertyUtils是以原本的类型对javabean进行操作。如果类型不对,就会有argument type mismatch异常。  

      理解了相应的原理,那些现成的工具用起来就会更舒服,如Beanutils与 PropertyUtils工具。这两个工具设置属性的时候一个主要区别是PropertyUtils.getPropety方法获得的属性值的类型为该 属性本来的类型,而BeanUtils.getProperty则是将该属性的值转换成字符串后才返回。

  • 相关阅读:
    (二十)WebGIS中图层树功能的设计和实现
    WebGIS中矢量切图的初步研究
    百度兴趣点下载工具设计和实现
    服务端常规知识详解
    Shp数据批量导入Postgresql工具的原理和设计
    浅谈C#中一种类插件系统编写的简单方法(插件间、插件宿主间本身不需要通信)
    从底层开发谈WebGIS中实现地理长度固定的可视窗口的思路和方法
    用存储过程判断某个人员在一天的行进轨迹中是否有超过指定时间的停留
    Linux启动与禁止SSH用户及IP的登录
    JVM中的垃圾回收
  • 原文地址:https://www.cnblogs.com/lcngu/p/7352855.html
Copyright © 2011-2022 走看看