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

  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/lcngu/p/7352855.html
Copyright © 2011-2022 走看看