• 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则是将该属性的值转换成字符串后才返回。

  • 相关阅读:
    外部编辑Infopath的表单模板(xsn)
    安装SQL Server 2008时可能遇到性能计数器不一致的情况
    Windows应用程序中使用Windows验证方式要注意的地方
    在MOSS 2007中使用Web Capture这个WebPart
    MOSS 配置SSO的时候可能遇到"您没有执行此操作的权限"的错误
    基于Web的操作系统,是否有可能?
    ASP.NET 中对于异常的处理
    在读取站点地图时自动应用安全设置
    JavaScript中的Window窗口对象【转载】
    当动态TSQL语句遇到除零的问题
  • 原文地址:https://www.cnblogs.com/lcngu/p/7352855.html
Copyright © 2020-2023  润新知