02 July 2016

关于反射,Nutz中提供了Mirror类。这里是该类的帮助文档Mirror帮助文档。 看过这个文档后,使用Mirror是没有什么问题了。

## Mirror

Mirror中提供了针对反射的方法操作非常之多,总体类说分为以下几类:

  • 获取方法Method:获取所有方法或者指定方法,或者Getter方法
  • 获取属性:获取所有属性或者指定属性
  • 为指定的属性设置值
  • 类型判断
  • 其他工具类方法:
    • 获取范型参数类型
    • 根据注解查找属性
    • 获取对象的构造器

底层实现都是使用java.lang.reflect包里面的类,如下所示:

    java.lang.annotation.Annotation;
    java.lang.reflect.Array;
    java.lang.reflect.Constructor;
    java.lang.reflect.Field;
    java.lang.reflect.Method;
    java.lang.reflect.Modifier;
    java.lang.reflect.ParameterizedType;
    java.lang.reflect.Type;

由于该Mirror类封装的方法众多,所以这里不一一说明,仅挑选自己平时也用的一些来说明

获取对象中指定属性的值。

Mirror中针对属性的值获取,主要有以下几种方式,

  • 根据属性名获取该属性getter方法,然后调用getter方法获取属性值,伪代码如下:

      return getGetter(propName).invok(object);
    

    getGetter具体实现:使用propName来拼Getter方法名,使用”get” 和”is”开头来拼方法名。

  • 另外一种方法是获取属性Field,然后调用Field.get(object)获取该属性值

第二种方法我自己之前很少使用,主要是没有对java api系统看,不知道有这个方法。

获取注解信息

通过反射获取注解本身很简单;但是注解的应用太广泛了,以至于很多人反而容易忽视这个东西,这个就叫做熟视无睹。 Mirror中提供了getAnnotation(Class annType)方法来获取一个类中的注解信息。 实现上也简单精巧:

        do {
            ann = cc.getAnnotation(annType);
            cc = cc.getSuperclass();
        } while (null == ann && cc != Object.class);

上述代码从当前类型本身获取指定注解,如果获取不到注解,就向上一层从父类获取,直到Object类型不在获取(不好喊Object).

lang中还有两个包也是为反射相关提供的功能,一个是org.nutz.lang.born,一个是org.nutz.lang.reflect

org.nutz.lang.born

born包中主要封装了有别于传统的new关键字创建对象的方法。

该package下有一个顶级接口Borning,该接口中定义了一个接口方法:

//通过给定参数生成一个对象
T born(Object... args);

其他类基本都实现了该接口,并且实现了born方法。挑选几个关键的说明下

ArrayBorning

顾名思义,根据一个参数生成一个对象数组; 这里注意,生成的对象数组中并没有对象数据,只是一个指定长度的空的对象数组, ArrayBorning 的born方法虽然支持多个参数,单实际上只使用了第一个参数,且默认认为第一个参数为数字(初始化数组长度用)

Array.newInstance(eleType, ((Number) arg0).intValue());

实现通过调用java api中的java.lang.Array的newInstance方法

###ConstructorBorning

  • 根据构造函数对象,和构造参数生成一个对象
  • ConstructorBorning 的构造方法中传入构造函数对象Constructor(有没有听绕口令的感觉), born方法中传入构造参数
  • 具体实现也是调用java api中的Class的newInstance方法。
  • ConstructorCastingBorning和ConstructorBorning逻辑,用法差不多,只不过加入了对范型的支持

###小结

java虽然不是动态语言,但是通过反射机制也达到了一些动态语言具备的功能。对于嫌弃java语言不灵活的同学,可以多研究研究java的反射机制。说不定会发现java其实没有印象中那么死板。

nutz中还有一些反射相关的工具类,这里不一一说明,干說实在提不起兴趣,后面说多到其他模块用到这些基础模块的时候,再穿插的说吧。





Fork me on GitHub