zoukankan      html  css  js  c++  java
  • 内省概念及详解(MethodDescriptor、PropertyDescriptor)

    1. 内省(Introspector)概念

      ​ 内省Introspector 是Java提供的操作 JavaBean 的 API,用来访问某个属性的 getter/setter 方法。对于一个标准的 JavaBean 来说,它包括属性、get 方法和 set 方法,这是一个约定俗成的规范。为此 sun 提供了 Introspector 工具包,来使开发者更好或者更灵活的操作 JavaBean。

      例如:User类中有个name属性,那我们可以通过getName/setName来获取/设置name的值,内省就是通过Java提供的API访问属性的getName()/setName()方法。

    2. 内省与反射的区别

      ​ 在计算机科学中,内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。 不应该将内省和反射混淆。相对于内省,反射更进一步,是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。

    3. 内省常用类说明

      • Introspector 类提供了的 getBeanInfo()方法获取BeanInfo对象,可以拿到一个 JavaBean 的所有信息
      • BeanInfo 通过getPropertyDescriptors() 方法和 getMethodDescriptors()方法可以获取到PropertyDescriptors、MethodDescriptors对象
      • MethodDescriptor 类可以获得方法的元信息,比如方法名,参数个数,参数字段类型等
        • getMethod()获取方法的Method对象
        • getParameters() 获取方法的所有参数Parameter列表
        • getParameterTypes()获取方法的参数ParameterType列表
      • PropertyDescriptor 类的主要方法
        • getPropertyType(),获得属性的Class对象
        • getReadMethod()/getWriteMethod(),获得用于读取/写入属性值的方法
          • setReadMethod(Method readMethod)/setWriteMethod(Method writeMethod),设置用于读取/写入属性值的方法
    4. 代码演示

      • MethodDescriptor 详解

        // 使用Introspector获取BeanInfo对象
        BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
        // 使用BeanInfo对象获取到MethodDescriptor列表
        MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
        for (MethodDescriptor methodDescriptor : methodDescriptors) {
          // 获取方法Method对象
          Method method = methodDescriptor.getMethod();
          // 获取方法名称
          String methodName = method.getName();
        
          // 参数类型列表
          List<String> parameterTypeNames = new ArrayList<>();
          Class<?>[] parameterTypes = method.getParameterTypes();
          if (parameterTypes!=null && parameterTypes.length>0){
            Arrays.stream(parameterTypes).forEach(x-> {
              String name = x.getName();
              parameterTypeNames.add(name);
            });
          }
        
          // 获取方法参数Parameter数组
          Parameter[] parameters = method.getParameters();
          // 参数名称列表
          List<String> parameterNames = new ArrayList<>();
          if (parameters!=null && parameters.length>0){
            parameterNames = Arrays.stream(parameters).map(Parameter::getName).collect(Collectors.toList());
          }
        
          System.out.println("方法名称:"+methodName +" 参数类型列表:"+parameterTypeNames+" 参数名称列表:"+parameterNames);
        
      • PropertyDescriptors详解

        // 使用Introspector获取BeanInfo对象
        BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
        // 使用BeanInfo对象获取到PropertyDescriptor列表
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor :propertyDescriptors) {
            // 获取属性名称
            String name = propertyDescriptor.getName();
            if ("class".equals(name)){
                continue;
            }
            // 获取setter方法
            Method writeMethod = propertyDescriptor.getWriteMethod();
            // 获取getter方法
            Method readMethod = propertyDescriptor.getReadMethod();
            System.out.println("属性名称:"+name+
                                " 赋值方法:"+writeMethod.getName()+
                                " 获取方法:"+readMethod.getName());
        }
        
        // 利用反射创建对象
        User user = User.class.newInstance();
        // 创建PropertyDescriptor对象
        PropertyDescriptor propertyDescriptor = new PropertyDescriptor("name",User.class);
        
        // 获取写入方法并执行
        Method writeMethod = propertyDescriptor.getWriteMethod();
        writeMethod.invoke(user,"Rangers");
        
        // 获取读取方法并执行
        Method readMethod = propertyDescriptor.getReadMethod();
        Object readPropertyValue = readMethod.invoke(user);
        System.out.println("ReadMethod获取到到属性值:"+readPropertyValue);
        System.out.println("getter获取到到属性值:"+user.getName());
        
        // 设置写入方法并执行
        Method writeMd = User.class.getDeclaredMethod("setOoo",String.class);
        propertyDescriptor.setWriteMethod(writeMd);
        Method writeMethodAgain = propertyDescriptor.getWriteMethod();
        writeMethodAgain.invoke(user, "ooo");
        System.out.println("设置写入方法重新赋值:"+user.getName());
        
  • 相关阅读:
    Android性能优化典范(转)
    java分形树
    android通过pc脚本执行sqlite3脚本
    针对JD-GUI
    三星的中低端机使用AsyncTask的问题
    Github简明教程(转)
    android 5.0 (lollipop)源码编译环境搭建(Mac OS X)
    排队接水
    幂次方
    2020/4/12
  • 原文地址:https://www.cnblogs.com/rangers-sun/p/14511006.html
Copyright © 2011-2022 走看看