ButterKnife:Element,Type

element指的是一系列与之相关的接口集合,用于建模java编程语言元素的接口,它们位于javax.lang.model.element包下面,在jdk安装目录中可以看到element相关类:
在这里插入图片描述

element是代表程序的一个元素,这个元素可以是:包、类/接口、属性变量、方法/方法形参、泛型参数。element是java-apt(编译时注解处理器)技术的基础,因此如果要编写此类框架,熟悉element是必须的。各种element所代表的元素类型,如下图
在这里插入图片描述

Element接口族与Type接口族区别

Element所代表的元素只在编译期可见,用于保存元素在编译期的各种状态,而Type所代表的元素是运行期可见,用于保存元素在运行期的各种状态。

解析

在解析之前,先来看下javax.lang.model包下的几个顶级接口, javax.lang.model.element包中有几个类是其子接口.

UnknownEntityException

路径:C:\Program Files\Java\jdk1.8.0_301\src\javax\lang\model。表示未知类型的实体遇到的异常的超类。,如果语言有新的特性和新的结构类型出现,则这种情况可能会发生。访问者可能会抛出此异常的子类,以指示访问者是为该语言的先前版本创建的。

这些异常的公共超类允许单个catch块对代码进行统一处理。

该异常继承自RuntimeException.代码如下:

public class UnknownEntityException extends RuntimeException {

    private static final long serialVersionUID = 269L;

    /**
     * Creates a new {@code UnknownEntityException} with the specified
     * detail message.
     *
     * @param message the detail message
     */
    protected UnknownEntityException(String message) {
        super(message);
    }
}

SourceVersion

代表Java™ programming language的版本的枚举.有关特定版本的信息,请参阅对应版本Java版语言规范。该类会随着java的不断发布来跟新该类.该类的代码如下:

public enum SourceVersion {
    /*
     * Summary of language evolution
     * 1.1: nested classes
     * 1.2: strictfp
     * 1.3: no changes
     * 1.4: assert
     * 1.5: annotations, generics, autoboxing, var-args...
     * 1.6: no changes
     * 1.7: diamond syntax, try-with-resources, etc.
     * 1.8: lambda expressions and default methods
     * java语言演变的清单摘要:
     * 1.1: 类嵌套
     * 1.2: 支持strictfp
     * 1.3: 没有变化
     * 1.4: 断言
     * 1.5: 注解,泛型,自动装箱,可变参数
     * 1.6: 没有变化
     * 1.7: diamond syntax, try-with-resources, etc.
     * 1.8: lambda 表达式,默认方法
     */

    /**
     * The original version.
     *
     * The language described in
     * <cite>The Java&trade; Language Specification, First Edition</cite>.
     * java语言的第一版,在The Java™ Language Specification第一版中有描述
     */
    RELEASE_0,

    /**
     * The version recognized by the Java Platform 1.1.
     *
     * The language is {@code RELEASE_0} augmented with nested classes as described in the 1.1 update to
     * <cite>The Java&trade; Language Specification, First Edition</cite>.
     * java 1.1 版本.
     * 该版本比在The Java™ Language Specification第一版中新增了嵌套类
     */
    RELEASE_1,

    /**
     * The version recognized by the Java 2 Platform, Standard Edition,
     * v 1.2.
     * java 1.2 版本
     *
     * The language described in
     * <cite>The Java&trade; Language Specification,
     * Second Edition</cite>, which includes the {@code
     * strictfp} modifier.
     * 该版本在The Java™ Language Specification第二版中有描述,该版本新增了strictfp修饰符
     */
    RELEASE_2,

    /**
     * The version recognized by the Java 2 Platform, Standard Edition,
     * v 1.3.
     *
     * No major changes from {@code RELEASE_2}.
     * 1.3 版本.和1.2相比没有变化
     */
    RELEASE_3,

    /**
     * The version recognized by the Java 2 Platform, Standard Edition,
     * v 1.4.
     *
     * Added a simple assertion facility.
     * 1.4版本.增加了断言机制
     */
    RELEASE_4,

    /**
     * The version recognized by the Java 2 Platform, Standard
     * Edition 5.0.
     *
     * The language described in
     * <cite>The Java&trade; Language Specification,
     * Third Edition</cite>.  First release to support
     * generics, annotations, autoboxing, var-args, enhanced {@code
     * for} loop, and hexadecimal floating-point literals.

     * java 2 Platform, Standard Edition 5.0--> jdk 1.5.
     * 在The Java™ Language Specification第三版中有描述.支持泛型,注解,可变参数
     * 增加for循环,16进制的浮点字面量
     * 
     */
    RELEASE_5,

    /**
     * The version recognized by the Java Platform, Standard Edition
     * 6.
     *
     * No major changes from {@code RELEASE_5}.
     * jdk1.6。 和jdk1.5没有任何变化
     */
    RELEASE_6,

    /**
     * The version recognized by the Java Platform, Standard Edition
     * 7.
     *
     * Additions in this release include, diamond syntax for
     * constructors, {@code try}-with-resources, strings in switch,
     * binary literals, and multi-catch.
     * @since 1.7
     * jdk 1.7. 支持diamond syntax,try-with-resources,switch支持string,
     * 二进制字面量,multi-catch
     */
    RELEASE_7,

    /**
     * The version recognized by the Java Platform, Standard Edition
     * 8.
     *
     * Additions in this release include lambda expressions and default methods.
     * @since 1.8
     * jdk 1.8.支持lambda 表达式,默认方法
     */
    RELEASE_8;

    // Note that when adding constants for newer releases, the
    // behavior of latest() and latestSupported() must be updated too.
    // 当有信版本对应的枚举添加到该类中时,对应的latest()和 latestSupported()方法的
    // 实现也应该进行修改,使其返回最新的版本对应的枚举

    /**
     * Returns the latest source version that can be modeled.
     * 返回最新的版本
     * @return the latest source version that can be modeled
     */
    public static SourceVersion latest() {
        return RELEASE_8;
    }

    private static final SourceVersion latestSupported = getLatestSupported();

    private static SourceVersion getLatestSupported() {
        try {
            String specVersion = System.getProperty("java.specification.version");

            if ("1.8".equals(specVersion))
                return RELEASE_8;
            else if("1.7".equals(specVersion))
                return RELEASE_7;
            else if("1.6".equals(specVersion))
                return RELEASE_6;
        } catch (SecurityException se) {}

        return RELEASE_5;
    }

    /**
     * Returns the latest source version fully supported by the
     * current execution environment.  {@code RELEASE_5} or later must
     * be returned.
     * 返回当前运行环境中完全支持的最新版本,返回值必须是RELEASE_5或者是最新版本
     *
     * @return the latest source version that is fully supported
     */
    public static SourceVersion latestSupported() {
        return latestSupported;
    }

    /**
     * 判断名称是否为最新源版本中的语法有效标识符(简单名称)或关键字.
     * 该方法只有在给定name的首字符在调用Character.isJavaIdentifierStart(int)时返回
     * true,同时接下来的字符在Character.isJavaIdentifierPart(int) 中返回true时,该
     * 方法才最终返回true.
     * 此方法对应常规标识符、关键字和文本“true”、“false”和“null"返回true。对于所有其他字符串返回false。
     *
     */
    public static boolean isIdentifier(CharSequence name) {
        String id = name.toString();

        if (id.length() == 0) {
            return false;
        }
        int cp = id.codePointAt(0);
        if (!Character.isJavaIdentifierStart(cp)) {
            return false;
        }
        for (int i = Character.charCount(cp);
                i < id.length();
                i += Character.charCount(cp)) {
            cp = id.codePointAt(i);
            if (!Character.isJavaIdentifierPart(cp)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断名称是否是最新源代码中语法有效限定名.与isIdentifier()方法不同,
     * 对于关键字和字面量,该方法返回false
     */ 
    public static boolean isName(CharSequence name) {
        String id = name.toString();

        for(String s : id.split("\\.", -1)) {
            if (!isIdentifier(s) || isKeyword(s))
                return false;
        }
        return true;
    }

    // keywords 保存的是java语言最新版本的关键字
    private final static Set<String> keywords;
    static {
        Set<String> s = new HashSet<String>();
        String [] kws = {
            "abstract", "continue",     "for",          "new",          "switch",
            "assert",   "default",      "if",           "package",      "synchronized",
            "boolean",  "do",           "goto",         "private",      "this",
            "break",    "double",       "implements",   "protected",    "throw",
            "byte",     "else",         "import",       "public",       "throws",
            "case",     "enum",         "instanceof",   "return",       "transient",
            "catch",    "extends",      "int",          "short",        "try",
            "char",     "final",        "interface",    "static",       "void",
            "class",    "finally",      "long",         "strictfp",     "volatile",
            "const",    "float",        "native",       "super",        "while",
            // literals
            "null",     "true",         "false"
        };
        for(String kw : kws)
            s.add(kw);
        keywords = Collections.unmodifiableSet(s);
    }

    /**
     * 判断给定的字符串是否是Java最新版本的关键字或者是字面量
     */
    public static boolean isKeyword(CharSequence s) {
        String keywordOrLiteral = s.toString();
        return keywords.contains(keywordOrLiteral);
    }
}

这里,有些java语法中的特性是很少接触过的,或者对应的说法没有听过.这里就简要介绍一下.

strictfp修饰符: 如果表达式的类型为float或double,那么就会有一个问题,该表达式的值到底是从哪个值集(详情,请看JLS 4.2.3节)中导出的,这由值集转换规则(JLS 5.1.13)决定,这些规则又一轮于该表达式是否是FP-严格的.每个常量表达式都是FP-严格的.如果表达式不是常量表达式,那么就会考虑包含该表达式的所有类声明,接口声明和方法声明.如果任何这种声明有strictfp修饰符,那么该表达式就是FP-严格的.(JLS 15.4)

diamond syntax: 在jdk 1.7 之前,我们是这样写代码的:

Map<Integer, Map<String, String>> usersLists =
new HashMap<Integer, Map<String, String>>();

jdk 1.7 之后呢,我们可以这样写:

Map<Integer, Map<String, String>> usersLists = new HashMap<>();

AnnotatedConstruct

表示一个可以被注解的结构(元素),这个结构可以是element和type.element上的注释位于声明上 ,type上的注释位于type名称的特定用途上
在下面的定义中,注释A具有注释类型AT 。 如果AT是可重复的注释类型,则包含注释的类型是ATC 。

注解A直接声明在C上,如果是:

(1)A 显示或者隐示的声明在C的源代码上.通过,如果一个注解出现在C所对应的源代码中,那么A就是显示的被应用于C.如果有多个AT类型的注解存在于C,那么如果该AT是可重复注解,那么就称ATC被隐式的声明在C上.
(2)A 出现在C所对应的可执行文件中,类如类文件中的RuntimeVisibleAnnotations(运行时可见的注解) 和 RuntimeVisibleParameterAnnotations(运行时可见的参数注解)
注解A声明在C上,如果是:

注解A直接声明在C上
AT注解没有声明在C上,同时C是一个类,同时AT是可以继承的,同时注解A出现在C的父类中
注解A间接的声明在C上,如果满足如下2点:

AT是一个可重复注解,其可重复的注解类型为ATC
ATC类型的注解直接声明在C上,同时A是该ATC注解中valu方法的返回值类型.
注解A与C是关联的,如果是:

A 直接或者间接的声明在C上
AT没有直接或者间接的声明在C上,同时C是一个类,同时AT是可继承的,同时A与C的父类是关联的.
关于这部分的内容,可以参阅 JLS 9.6,9.6.3.3

代码如下:

public interface AnnotatedConstruct {
    /**
      *  返回直接声明在该结构上的注解.
      *  如果没有直接声明的注解,则返回空集合.    
      *  关于AnnotationMirror,在后面会有介绍
     */
    List<? extends AnnotationMirror> getAnnotationMirrors();

    /**
      *  返回指定类型所对应的注解,如果不存在,则返回null.
      *  注解的返回值可能会包含指定类型的class的元素.这个class不能直接返回:
      *  定位和加载类(如要使用的类加载器)所需的信息不可用,并且该类可能根本不可加载。
      *  通过调用返回的注释上的相关方法尝试读取Class对象将导致MirroredTypeException,从中可以提取相应的TypeMirror。类似地,尝试读取Class[]-元素会导致MirroredTypesException
      *  注意:此方法与此相关接口中的其他方法不同。它对运行时反射信息(当前加载到VM中的注
      *  解类型的表示)进行操作,而不是对这些接口定义和使用的表示进行操作。因此,在调用由
      *  反射返回的注解对象上的方法时,对返回的注解对象上调用方法可以引发许多异常。此方法是
      *  调用方用于编写,已知的固定类型的注解类型上操作的。
      *  具体可以参考 JLS 9.6.1 Annotation Type Elements
     */
    <A extends Annotation> A getAnnotation(Class<A> annotationType);

    /**
     * 返回与该结构体关联的注解.
     * 如果没有的话,则返回长度为0的数组.
     * 注解的顺序是按照直接或者间接的声明的顺序,间接声明的注解就好像直接声明在C上一样.
     * 此方法与getAnnotation(Class)的区别在于,此方法检测其参数是否为可重复注解类型,如果是,则试图通过“looking through”来查找该类型的一个或多个容器注解。
     */
    <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType);
}

directly present、indirectly present、present、associated

首先需要熟悉四种关系(元素与注解)

1、directly present

直接存在或者翻译为直接引用。当一个注解直接在元素上引用时,则为直接引用,比如下面代码,@Action就是直接引用:

@Action("上课")
public class Student {
 
}
2、indirectly present

间接存在或间接引用。当一个注解A并没有注解引用在一个类E上,但是包含这个注解A的注解B被E直接引用了,这属于E对A的间接引用。可参考下面实例。

3、present

引用。有两种情况都属于引用类型

(1)directly present关系肯定是present
(2)一个注解A(为可继承的,用@Inherited标识注解)直接引用于E类的超类F,那么E与A的关系则为引用关系

4、associated

关联。存在四种情况则为关联关系
(1)直接引用关系
(2)间接引用关系
(3)引用关系
(4)一个注解A(为可继承的,用@Inherited标识注解)与E类的超类F相关联,那么E与A的关系也为关联关系
在这里插入图片描述

可重复注解

在JDK 8 之前,注解不⽀持重复修饰同⼀个程序单元,所以必须采取技巧性的代码来处理这种需求.其做法是先创建⼀个普通的注解,⽐如下⾯

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
 String value() default "";
}

接着再创建⼀个容器注解,其某⼀个成员变量的类型是上⾯注解的数组类型,⽐如:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnoContainer {
 MyAnno[] value();
}

之后就把容器注解修饰在某个程序单元上,value成员变量就指定多个想重复出现的注解,⽐如

@MyAnnoContainer({@MyAnno("a"),@MyAnno("b")})
public class UserInfoEntity {
}

上⾯的实现⽅式语义不明确,因为⽬的是想多次出现MyAnno注解,但实际修饰在类上的却是另⼀个注解MyAnnoContainer.

在JDK8之后推出了⼀个@Repeatable元注解,此注解直接添加到MyAnno注解上,然后给@Repeatable元注解的value属性指定容器注解即可.最后直接把MyAnno注解修饰在程序单元上.最后的代码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(value = MyAnnoContainer.class )
public @interface MyAnno {
 String value() default "";
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnoContainer {
 MyAnno[] value();
}
@MyAnno("a")
@MyAnno("b")
public class UserInfoEntity {
}

在UserInfoEntity上修饰了多个@MyAnno之后就不能修饰容器注解MyAnnoContainer了.

想获取这个可重复的注解可以利⽤JDK先推出的⽅法getAnnotationsByType⽅法,如果找不到指定的注解就返回⼀个⻓度为0的数组.⽐如下⾯的代码

Class<UserInfoEntity> clazz = UserInfoEntity.class;
MyAnno[] myAnnos = clazz.getAnnotationsByType(MyAnno.class);
for(MyAnno anno:myAnnos) {
 System.out.println(anno.value());
}

这种可重复的注解利⽤getDeclaredAnnotation⽅法是取不到的.返回的是null

类型注解

在JDK 8 之前依据@Target设定注解可以修饰的地⽅,主要可以修饰的地⽅有类型,⽅法,字段,参数等.从JDK8开始,注解可以⽤在任何使⽤类型的地⽅,⽐如初始化(new)⼀个对象,使⽤implements表达式时.⽐如下⾯的代码

//实例化对象时
new @Interned MyObject();
//类型转换时
myString = (@NonNull String) str;
//实现语句时
class UnmodifiableList<T> implements
 @Readonly List<@Readonly T> { ... }
// 异常声明时.
void monitorTemperature() throws
 @Critical TemperatureException { ... }
// 泛型声明时
List<@NotNull String> list

定义⼀个这样的类型注解与定义普通的注解类似,只需要指定 Target 为
ElementType.TYPE_PARAMETER 或者 ElementType.TYPE_USE,或者同时指定这两个 Target。⽐如:

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
public @interface MyAnnotation {
}

Java 8 通过引⼊ Type Annotation,使得开发者可以在更多的地⽅使⽤ Annotation,从⽽能够更全⾯地对代码进⾏分析以及进⾏更强的类型检查.

想让这些类型其作⽤,还需要这个注解的处理器,以便在编译的时候利⽤这些检查的注解处理器解析这些注解.在https://checkerframework.org/⽹址有⼀个这样的注解解析器的使⽤说明.

下来我们就来看一下javax.lang.model.element包中的几个接口.

AnnotationMirror

代表一个注解.注解将值与注解类型的每个元素相关联。

注解之间的比较应该使用equals方法.无法保证任何特定的注解都是由一个对象来表示.

public interface AnnotationMirror {

    /**
     * 返回该注解的类型.
     */
    DeclaredType getAnnotationType();

    /**
     * 返回该注解的元素值.
     * 返回值为由对应的元素和它对应的值组成的map.
     * 只包括那些在注解中显式设置值的元素,而不包括那些隐式的默认值的元素。map中的顺序与注释的源中出现的值的顺序相匹配。
     * 注意如果是一个标记注解,则会返回空map.
     * 如果想要填充默认值的元素,使用Elements.getElementValuesWithDefaults()方法.
     */
    Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValues();
}

AnnotationValue

代表注解元素的类型。其类型为:

(1)原始类型对应的包装类
(2)String
(3)TypeMirror
(4)VariableElement(代表枚举)
(5)AnnotationMirror
(6)List

public interface AnnotationValue {

    /**
     * 返回该注解元素对应的值
     */
    Object getValue();

    /**
     * 返回该注解元素对应的值所对应的字符串形式
     */
    String toString();

    /**
     * 访问者模式
     * <R>-->该方法的返回值类型.
     * <P>-->额外添加的参数的类型
     * 参数P --> 额外添加的参数
     */
    <R, P> R accept(AnnotationValueVisitor<R, P> v, P p);
}

AnnotationValueVisitor

注释类型元素的值的访问者,使用访问者设计模式的变体。与标准访问者基于类型层次结构中成员的具体类型进行分派不同,该访问者基于所存储的数据类型进行分派;存储时没有子类之间的区别,如boolean与int.实现此接口的类用于操作在编译时未知该类型的值.如果访问者传递给了元素值的accept 方法,则所对应的visitXYZ 方法会被调用.

如果附加参数p为空,实现此接口的类可以抛出NullPointerException,也可以不抛出NullPointerException;有关详细信息,请参阅实现类的文档。

警告:有可能将方法添加到该接口,以适应添加到Java编程语言未来版本的新的、目前未知的语言结构。因此,直接实现此接口的访问者类可能与平台的未来版本不兼容。为了避免这种源不兼容性,我们鼓励访问者实现扩展实现这个接口的适当的抽象访问者类。但是,API通常应该使用这个访问者接口作为参数、返回类型等的类型,而不是一个抽象类。

注意,如果将用于适应新语言构造的方法作为默认方法添加,则可以以与源兼容的方式添加它们。但是,默认方法只在Java SE 8和更高版本上可用,javax.lang.model.* 捆绑在Java SE 8中的包也需要在Java SE 7上运行。因此,在扩展javax.lang.model.* 以覆盖Java SE 8语言特性时不能使用默认方法。但是,默认方法可以用于javax.lang.model.* 包的后续修订,这些包只需要在Java SE 8和更高的平台版本上运行。

该接口是一个泛型接口.其泛型参数介绍如下:

R –> 该访问方法的返回值
P –> 该访问方法额外添加的参数

public interface AnnotationValueVisitor<R, P> {
    /**
     * 访问AnnotationValue
     */
    R visit(AnnotationValue av, P p);

    /**
     * 和v.visit(av, null)方法具有同样效果的方法
     */
    R visit(AnnotationValue av);


    R visitBoolean(boolean b, P p);


    R visitByte(byte b, P p);


    R visitChar(char c, P p);


    R visitDouble(double d, P p);


    R visitFloat(float f, P p);


    R visitInt(int i, P p);


    R visitLong(long i, P p);


    R visitShort(short s, P p);


    R visitString(String s, P p);


    R visitType(TypeMirror t, P p);


    R visitEnumConstant(VariableElement c, P p);


    R visitAnnotation(AnnotationMirror a, P p);


    R visitArray(List<? extends AnnotationValue> vals, P p);

    /**
     * 访问注解值是一个未知类型的方法.
     * 这可以在语言的进化和新的类型可以存储在一个注解时出现这种情况。
     */
    R visitUnknown(AnnotationValue av, P p);
}

Element

该接口继承自javax.lang.model.AnnotatedConstruct.该接口代表java程序中的元素,比如包,类,或者方法.每个元素表示静态、语言级别的结构(而不是虚拟机的运行时结构)。

Element见的比较应该使用equals(Object)方法,无法保证任何特定的元素都是用一个对象来表示的

要实现基于元素对象类的操作,要么使用ElementVisitor,要么使用getKind方法的结果。使用instanceof不一定是确定此建模层次结构中对象的有效类的可靠习惯用法,因为实现可以选择让单个对象实现多个Element子接口。

public interface Element extends javax.lang.model.AnnotatedConstruct {
    /**
     * 返回该元素定义的类型。
     * 泛型元素定义了一系列类型,而不仅仅是一个类型。如果这是一个泛型元素,则返回一个原型
     * 类型。这是元素在对应于它自己的正式类型参数的类型变量上的调用。例如,对于泛型类元素
     * C<N extends Number>,返回参数化类型C<N>。类型实用程序接口有更一般的方法来获取元
     * 素定义的所有类型的范围。 
     */
    TypeMirror asType();

    /**
     * 返回该元素的类型
     */
    ElementKind getKind();

    /**
     * 返回该元素的修饰符,包括注解.
     * 隐式修饰符也包含,比如接口方法中的public和static
     */
    Set<Modifier> getModifiers();

    /**
     * 返回该元素的简单名称.泛型类型的名称不包括对其正式类型参数的任何引用。
     * 举例,java.util.Set<E>的简单名称是Set.
     * 如果该元素代表的是未命名包,则返回一个空 Name.
     * 如果代表的是构造器,则返回<init>所对应的Name.如果代表的是静态代码块,则返回的是<clinit>
     * 如果代表的是匿名类或者是初始代码块,则返回一个空 Name.
     */
    Name getSimpleName();

    /**
     * 返回包围该元素的最内层的元素.
     * 如果这个元素的声明紧接在另一个元素的声明中,则返回另一个元素。
     * 如果这是顶级类型,则返回其包。
     * 如果这是一个包,则返回null。
     * 如果这是类型参数,则返回类型参数的泛型元素。
     * 如果这是一个方法或构造函数参数,则返回声明该参数的可执行元素。
     */
    Element getEnclosingElement();

    /**
     * 返回该元素所包含的元素.
     * 类或接口被认为包含了它直接声明的字段、方法、构造函数和成员类型.包直接包含了顶级类和接
     * 口,但不包含其子包。其他类型的元素目前不被认为包含任何元素;然而,随着这个API或编程语
     * 言的发展,这些元素可能会改变
     */
    List<? extends Element> getEnclosedElements();

    /**
     * 当给定的参数和当前类代表同一个元素时返回true,否则,返回false.
     * 注意,元素的标识涉及不能直接从元素的方法中访问的隐式状态,包括关于不相关类型的存在的
     * 状态。即使“同一个”元素正在被建模,由这些接口的不同实现创建的元素对象也不应该期望相
     * 等;这类似于通过不同的类加载器加载的同一个类文件的Class对象是不同的
     *
     */
    @Override
    boolean equals(Object obj);

    /**
     * 基于Object.hashCode
     */
    @Override
    int hashCode();


    /**
     * 获得直接声明在该元素上的注解
     * 如果要获得继承的注解,使用Elements#getAllAnnotationMirrors(Element)方法.
     */
    @Override
    List<? extends AnnotationMirror> getAnnotationMirrors();


    @Override
    <A extends Annotation> A getAnnotation(Class<A> annotationType);


    <R, P> R accept(ElementVisitor<R, P> v, P p);
}

ElementKind

关于元素类型的枚举

public enum ElementKind {

    /** 包 */
    PACKAGE,

    // 声明类型
    /** 枚举 */
    ENUM,

    CLASS,
    /** 注解类型 */
    ANNOTATION_TYPE,
    /** 接口 */
    INTERFACE,

    // 变量
    /** 一个枚举常量 */
    ENUM_CONSTANT,
    /**
     * 字段
     */
    FIELD,
    /** 方法或者构造器中的参数 */
    PARAMETER,
    /** 本地变量 */
    LOCAL_VARIABLE,
    /** try-catch中的catch语句的异常类型*/
    EXCEPTION_PARAMETER,

    // 可执行的类型
    /** 方法 */
    METHOD,
    /** 构造器 */
    CONSTRUCTOR,
    /** 静态初始块 */
    STATIC_INIT,
    /** 初始块 */
    INSTANCE_INIT,

    /** 类型参数 */
    TYPE_PARAMETER,

    /**
     * An implementation-reserved element.  This is not the element
     * you are looking for.
     */
    OTHER,

    /**
     * A resource variable.
     * @since 1.7
     */
    RESOURCE_VARIABLE;


    /**
     * 如果当前是CLASS或者是枚举则返回true
     */
    public boolean isClass() {
        return this == CLASS || this == ENUM;
    }

    /**
     * 如果当前是INTERFACE或者ANNOTATION_TYPE则返回true
     */
    public boolean isInterface() {
        return this == INTERFACE || this == ANNOTATION_TYPE;
    }

    /**
     * 如果当前是FIELD或者是ENUM_CONSTANT则返回true
     */
    public boolean isField() {
        return this == FIELD || this == ENUM_CONSTANT;
    }
}

ElementVisitor

Element的访问者接口.

public interface ElementVisitor<R, P> {

    R visit(Element e, P p);


    R visit(Element e);


    R visitPackage(PackageElement e, P p);


    R visitType(TypeElement e, P p);


    R visitVariable(VariableElement e, P p);


    R visitExecutable(ExecutableElement e, P p);


    R visitTypeParameter(TypeParameterElement e, P p);


    R visitUnknown(Element e, P p);
}

Parameterizable

代表该元素有类型参数的接口,继承自Element.

public interface Parameterizable extends Element {
    /**
      * 以声明顺序返回类型元素的形式类型参数
      */
    List<? extends TypeParameterElement> getTypeParameters();
}

ExecutableElement

代表一个类或者接口的方法,构造器,或者初始块(静态或者实例的),包括注解类型.是Parameterizable的子接口.

public interface ExecutableElement extends Element, Parameterizable {
    /**
     * 按声明顺序返回形式类型参数
     */
    List<? extends TypeParameterElement> getTypeParameters();

    /**
     * 返回该类的返回类型.如果当前不是方法或者该方法没有返回值,则返回由
     * NoType和TypeKind#VOID组成的TypeMirror
     */
    TypeMirror getReturnType();

    /**
     * 按照声明顺序返回该类所对应的形式参数
     */
    List<? extends VariableElement> getParameters();

    /**
     * 返回当前类型所对应的接收器类型,如果没有对应的接收器,则返回由javax.lang.model.type.NoType和javax.lang.model.type.TypeKind#NONE组成的TypeMirror
     * 如果当前是一个实例方法,构造器或者是一个内部类,则其接收器类型可以由javax.lang.model.element.Element.getEnclosingElement()方法获得.
     * 如果当前是一个静态方法,或者是非内部类的构造器,或者是初始块(静态的或者是实例的),则没有接收器类型
     * 
     */
    TypeMirror getReceiverType();

    /**
     * 如果当前所对应的方法或者构造器接受可变参数,则返回true
     */
    boolean isVarArgs();

    /**
     * 如果当前所对应的是一个默认方法,则返回true
     */
    boolean isDefault();

    /**
     * 返回当前所对应的方法或者是构造器所对应的异常列表
     */
    List<? extends TypeMirror> getThrownTypes();

    /**
     * 如果当前对应的是一个注解元素,则返回其默认值,如果不是,或者该注解元素没有对应的默认值,则返回null
     */
    AnnotationValue getDefaultValue();

    /**
     * 返回构造器,方法或者初始化块所对应的Name.对于构造器,返回<init>,对于静态代码块,返回<clinit>,对于匿名类或者实例代码块,返回空的Name
     */
    @Override
    Name getSimpleName();
}

QualifiedNameable

代表有限定名的元素的接口.

public interface QualifiedNameable extends Element {
    /**
     * 返回该元素所对应的限定名
     */
    Name getQualifiedName();
}

TypeElement

表示类或接口程序元素。 提供对类型及其成员的信息的访问。 请注意,枚举类型是一种类,注释类型是一种接口。
TypeElement表示类或接口元素 ,而DeclaredType表示类或接口类型 ,后者是前者的使用(或调用 )。 泛型类型的区别最为明显,单个元素可以为其定义整个类型。 例如,元素java.util.Set对应于参数化类型java.util.Set和java.util.Set (以及许多其他类型),以及原始类型java.util.Set 。

返回元素列表的此接口的每个方法将按照对于基础程序信息源自然的顺序返回它们。 例如,如果底层信息源是Java源代码,那么元素将以源代码顺序返回。

public interface TypeElement extends Element, Parameterizable, QualifiedNameable {
    /**
     * 返回在该类或者接口中直接声明的字段,方法,构造器和成员类型.
     * 包括(隐式的)默认构造器和在枚举类型中隐式的values和valueOf方法.

     注意,作为该接口所需的一般要求和排序行为的特定实例,所包含的元素列表将以自然顺序返回,以作为关于该类型的信息的原始来源。例如,如果关于类型的信息源自源文件,则元素将以源代码顺序返回。(但是,在这种情况下,没有指定合成元素的排序,例如默认构造函数。)
     *
     */
    @Override
    List<? extends Element> getEnclosedElements();

    /**
     * 获得该类型的嵌套的类型
     */
    NestingKind getNestingKind();

    /**
     * 返回该类型的全限定名.更确切地说,它返回规范名称。对于没有标准名称的本地和匿名类,返
     * 回空名称。泛型类型的名称不包括对其正式类型参数的任何引用。例如,接口java.util.Set\<E\>
     * 的完全限定名是“java.util.Set”,嵌套类型使用“..”作为分隔符,
     * 如“java.util.Map.Entry”。
     */
    Name getQualifiedName();

    /**
     * 返回该类型的简单名称,对于匿名类,返回空name
     *
     */
    @Override
    Name getSimpleName();

    /**
     * 返回该类型对应的直接父类,如果该类是一个接口或者该类是Object,则返回由NoType和TypeKind#NONE组成的TypeMirror
     */
    TypeMirror getSuperclass();

    /**
     * 翻译1:如果当前是类,则返回实现的接口,如果是接口,则返回继承的接口
     * 翻译2:返回由此类直接实现或由此接口扩展的接口类型。

     */
    List<? extends TypeMirror> getInterfaces();

    /**
      * 按照声明顺序返回该类型的泛型参数
     */
    List<? extends TypeParameterElement> getTypeParameters();

    /**
     * 返回包下的顶级类型,并返回在词法上直接包围的嵌套类型
     */
    @Override
    Element getEnclosingElement();
}

NestingKind

对应嵌套类型的枚举类,嵌套类型有四种:顶级元素,成员,本地和匿名类.嵌套类型是一种非标准术语,用于表示这种分类。请注意,可能会在java平台的未来版本中添加其他嵌套类型

public enum NestingKind {
    /**
     * 顶级类型,没有被其他类型所包含
     */
    TOP_LEVEL,

    /**
     * 其他类型的一个成员类
     */
    MEMBER,

    /**
     * 在类型之外的结构中声明的命名类型(本地)
     */
    LOCAL,

    /**
     * 匿名类
     */
    ANONYMOUS;

    /**
     * 当前元素对应的是嵌套类型吗?嵌套类型元素是,不是顶层的任何元素。内部类型元素是任何非静态的嵌套类型元素
     */
    public boolean isNested() {
        return this != TOP_LEVEL;
    }
}

PackageElement

代表包的接口

public interface PackageElement extends Element, QualifiedNameable {

    /**
     * 返回这个包的全限定名称.这也就是包的规范名称.如果是当前对应的是未命名包,则返回一个空Name
     */
    Name getQualifiedName();

    /**
     * 返回这个包的简单名称.这也就是包的规范名称.如果是当前对应的是未命名包,则返回一个空Name
     */
    @Override
    Name getSimpleName();

    /**
     * 返回声明在本包下的顶级类和接口,对于子包中声明的类和接口,是不包含在返回值的
     */
    @Override
    List<? extends Element> getEnclosedElements();

    /**
     * 如果当前对应的是未命名的包,则返回true
     */
    boolean isUnnamed();

    /**
     * 如果本包没有被其他包所包含,则返回null
     */
    @Override
    Element getEnclosingElement();
}

TypeParameterElement

代表泛型类,接口,方法或者构造器的形式类型参数.一个类型参数就对应的一个类型变量

public interface TypeParameterElement extends Element {

    /**
     * 返回由该类型参数参数化的泛型类、接口、方法或构造函数
     */
    Element getGenericElement();

    /**
     * 返回此类型参数的边界。这是用于声明此类型参数的extends子句所给出的类型。如果没有显式使用extends子句,则java.lang.Object被认为是唯一绑定的。
     */
    List<? extends TypeMirror> getBounds();

    /**
     * 返回此类型参数的泛型元素。
     */
    @Override
    Element getEnclosingElement();
}

VariableElement

代表一个字段,枚举常量,方法或者构造器的参数,本地变量,try-with-resource中的resource 变量,或者是异常参数.

public interface VariableElement extends Element {

    /**
     * 如果当前对应的是fianl修饰的字段,是在编译期初始化的常量,则返回对应的值,否则返回null.
     * 其常量值可能是原始类型或者是String,如果是原始类型,则返回对应的包装类。
     * 不是所有的finale字段都是常量值,如枚举的常量就不认为是编译期的常量。若要具有常量值,字段的类型必须是原始类型或字符串。
     */
    Object getConstantValue();

    /**
     * 返回该元素的简单名称.
     * 对于在同一方法或者构造器的参数类来说,其名字应该与其他的参数是不同的.
     * 如果在源文件的名称不可视,则实现可以合成符合上述不同性要求的名称。
     *
     */
    @Override
    Name getSimpleName();

    /**
     * 返回该元素正在包围的元素.
     * 对于方法或者构造器参数所包围的元素是其所对应的参数
     *
     */
    @Override
    Element getEnclosingElement();
}

UnknownElementException

当遇到未知类型的元素时会抛出该异常.如果语言进化并将新类型的元素添加到Element的层次结构中,则会发生这种情况。可以由Element访问者抛出,以指示访问者是为语言的先前版本创建的。

public class UnknownElementException extends UnknownEntityException {

    private static final long serialVersionUID = 269L;

    private transient Element element;
    private transient Object parameter;

    /**
     * 创建一个新的UnknownElementException.参数p可能会用来提供一些该未知元素出现的信息.举例,如ElementVisitor的visit方法可能会传递他们的额外参数
     */
    public UnknownElementException(Element e, Object p) {
        super("Unknown element: " + e);
        element = e;
        this.parameter = p;
    }


    public Element getUnknownElement() {
        return element;
    }


    public Object getArgument() {
        return parameter;
    }
}

Type

在这里插入图片描述

TypeKind

该类是一个媒介,定义了java中各种类型所对应的枚举.

public enum TypeKind {
    /**
     * The primitive type {@code boolean}.
     * boolean的原始类型
     */
    BOOLEAN,

    /**
     * The primitive type {@code byte}.
     * byte的原始类型
     */
    BYTE,

    /**
     * The primitive type {@code short}.
     * short的原始类型
     */
    SHORT,

    /**
     * The primitive type {@code int}.
     * int的原始类型
     */
    INT,

    /**
     * The primitive type {@code long}.
     * long的原始类型
     */
    LONG,

    /**
     * The primitive type {@code char}.
     * char的原始类型
     */
    CHAR,

    /**
     * The primitive type {@code float}.
     * float的原始类型
     */
    FLOAT,

    /**
     * The primitive type {@code double}.
     * double的原始类型
     */
    DOUBLE,

    /**
     * The pseudo-type corresponding to the keyword {@code void}.
     * @see NoType
     * 代表void的伪类型
     */
    VOID,

    /**
     * A pseudo-type used where no actual type is appropriate.
     * @see NoType
     * 代表没有合适的类型与之对应的伪类型
     */
    NONE,

    /**
     * The null type.
     * 代表null的类型
     */
    NULL,

    /**
     * An array type.
     */
    ARRAY,

    /**
     * A class or interface type.
     * 代表类或者接口的类型
     */
    DECLARED,

    /**
     * A class or interface type that could not be resolved.
     * 代表无法进行解析的类或接口类型
     */
    ERROR,

    /**
     * A type variable.
     * 类型变量
     * 如一个类声明如下:    C<T,S> ,那么T,S就是类型变量
     */
    TYPEVAR,

    /**
     * A wildcard type argument.
     * 通配符.如:
     * ?,? extends Number,? super T
     */
    WILDCARD,

    /**
     * A pseudo-type corresponding to a package element.
     * @see NoType
     * 代表包的伪类型
     */
    PACKAGE,

    /**
     * A method, constructor, or initializer.
     * 代表方法,构造器,初始代码块
     */
    EXECUTABLE,

    /**
     * An implementation-reserved type.
     * This is not the type you are looking for.
     * 保留类型
     */
    OTHER,

    /**
      * A union type.
      * 联合类型
      * jdk1.7中的 try multi-catch 中异常的参数就是联合类型
      * @since 1.7
      */
    UNION,

    /**
      * An intersection type.
      * 交集类型
      * 如一个类有泛型参数,如<T extends Number & Runnable>,那么T extends Number & Runnable 就是交集类型
      *
      * @since 1.8
      */
    INTERSECTION;

    /**
     * Returns {@code true} if this kind corresponds to a primitive
     * type and {@code false} otherwise.
     * @return {@code true} if this kind corresponds to a primitive type
     * 判断是否是原生类型
     */
    public boolean isPrimitive() {
        switch(this) {
        case BOOLEAN:
        case BYTE:
        case SHORT:
        case INT:
        case LONG:
        case CHAR:
        case FLOAT:
        case DOUBLE:
            return true;

        default:
            return false;
        }
    }
}

TypeMirror

代表了java编程语言中的类型,包括原生类型,声明类型(类和接口),数组类型,类型变量,null类型.同时也包括通配符,可执行语句的签名和返回类型,包和void所对应的伪类型

public interface TypeMirror extends javax.lang.model.AnnotatedConstruct {

    /**
     * Returns the {@code kind} of this type.
     * 返回该类所对应的TypeKind
     *
     * @return the kind of this type
     */
    TypeKind getKind();

    /**
     * Obeys the general contract of {@link Object#equals Object.equals}.
     * This method does not, however, indicate whether two types represent
     * the same type.
     * Semantic comparisons of type equality should instead use
     * {@link Types#isSameType(TypeMirror, TypeMirror)}.
     * The results of {@code t1.equals(t2)} and
     * {@code Types.isSameType(t1, t2)} may differ.
     * 满足 Object#equals方法的语义,然而,本方法并不代表2个类型是同样的.语义上比较2个类      * 型是否相同应该使用Types#isSameType(TypeMirror, TypeMirror)方法,该方法的返回    *  值可能和Types.isSameType(t1, t2)的返回值不一样.
     * @param obj  the object to be compared with this type
     * @return {@code true} if the specified object is equal to this one
     */
    boolean equals(Object obj);

    /**
     * Obeys the general contract of {@link Object#hashCode Object.hashCode}.
     * 按照Object#hashCode的语义来实现
     * @see #equals
     */
    int hashCode();

    /**
     * Returns an informative string representation of this type.  If
     * possible, the string should be of a form suitable for
     * representing this type in source code.  Any names embedded in
     * the result are qualified if possible.
     * 返回此类型的字符串表示形式。如果可能的话,字符串应该是适合于在源代码中表示这种类型的形式。如果可能,嵌入在结果中的任何名称都是合格的。
     * @return a string representation of this type
     */
    String toString();

    /**
     * Applies a visitor to this type.
     *
     * @param <R> the return type of the visitor's methods
     * @param <P> the type of the additional parameter to the visitor's methods
     * @param v   the visitor operating on this type
     * @param p   additional parameter to the visitor
     * @return a visitor-specified result
     */
    <R, P> R accept(TypeVisitor<R, P> v, P p);
}

该类的子接口

ExecutableType

代表可执行的类型,如方法,构造器,初始代码块.可执行文件表示为某种引用类型的方法(或构造函数或初始化器)。如果引用类型是参数化的,那么它的实际类型参数被替换为该接口的方法返回的任何类型

public interface ExecutableType extends TypeMirror {

    /**
     * Returns the type variables declared by the formal type parameters
     * of this executable.
     * 返回该类型的类型变量.
     *
     * @return the type variables declared by the formal type parameters,
     *          or an empty list if there are none
     *          返回该类型的类型变量,或者空集合,如果该类型不是泛型的
     */
    List<? extends TypeVariable> getTypeVariables();

    /**
     * Returns the return type of this executable.
     * Returns a {@link NoType} with kind {@link TypeKind#VOID VOID}
     * if this executable is not a method, or is a method that does not
     * return a value.
     * 返回该类型的返回类型。当该类型不是方法,或者该方法没有返回值时,则该方法返回的是
     * NoType和TypeKind#VOID构成的TypeMirror
     *
     * @return the return type of this executable
     */
    TypeMirror getReturnType();

    /**
     * Returns the types of this executable's formal parameters.
     * 返回该类型的形式参数,如果没有的话,返回空集合
     * @return the types of this executable's formal parameters,
     *          or an empty list if there are none
     */
    List<? extends TypeMirror> getParameterTypes();

    /**
     * Returns the receiver type of this executable,
     * or {@link javax.lang.model.type.NoType NoType} with
     * kind {@link javax.lang.model.type.TypeKind#NONE NONE}
     * if the executable has no receiver type.
     * 返回该类型的接收器类型,如果该类型没有接收器,则返回NoType,TypeKind#NONE 构成的
     * TypeMirror
     * 
     * An executable which is an instance method, or a constructor of an
     * inner class, has a receiver type derived from the {@linkplain
     * ExecutableElement#getEnclosingElement declaring type}.
     * 一个实例方法,或者是内部类的构造器,有接收器类型。可以从xecutableElement#getEnclosingElement 获得

     * An executable which is a static method, or a constructor of a
     * non-inner class, or an initializer (static or instance), has no
     * receiver type.
     * 静态方法,不是内部类的构造器,或者是初始代码块(静态或者实例的),没有接收器类型
     *
     * @return the receiver type of this executable
     * @since 1.8
     */
    TypeMirror getReceiverType();

    /**
     * Returns the exceptions and other throwables listed in this
     * executable's {@code throws} clause.
     * 返回该类型的异常声明列表
     * @return the exceptions and other throwables listed in this
     *          executable's {@code throws} clause,
     *          or an empty list if there are none.
     */
    List<? extends TypeMirror> getThrownTypes();
}

关于接收器类型,在JLS P150 有说明,现摘抄如下

在实例方法中,接收器参数的类型必须是声明该方法的类或接口,而接收器的名字必须是this,否则,会产生编译时错误
在内部类构造器中,接收器参数的类型必须是作为该内部类的直接包围类型声明的类或接口,而接收器参数的名字必须是Identifier.this.其中,Identifire是作为该内部类的直接包围类型声明的类或接口的简单名,否则,就会产生编译时错误.

IntersectionType

代表交集类型.

交集类型可以隐式或显式地声明在程序中。例如,类型参数

public interface IntersectionType extends TypeMirror {

    /**
     * Return the bounds comprising this intersection type.
     * 获得对应的交集类型
     * @return the bounds of this intersection types.
     */
    List<? extends TypeMirror> getBounds();
}

NoType

在没有实际类型合适的情况下使用的伪类型.其情况如下:

(1)TypeKind#VOID –> 代表对应的void 关键字
(2)TypeKind#PACKAGE –> 对应packeage 的伪元素
(3)TypeKind#NONE –> 代表没有对应类型,如 Object 就没有父类

PrimitiveType

代表原始类型,包括 boolean,byte,short,int,long,char.float,double

public interface PrimitiveType extends TypeMirror {
}

ReferenceType

代表引用类型,包括类和接口,数组类型,类型变量,null.代表如下:

public interface ReferenceType extends TypeMirror {
}

ArrayType

代表数组类型,多为数组类型是一个数组类型其组件类型还是数组类型.代码如下:

public interface ArrayType extends ReferenceType {

    /**
     * Returns the component type of this array type.
     * 返回该数组类型对应的组件类型
     * @return the component type of this array type
     */
    TypeMirror getComponentType();
}

DeclaredType

代表声明类型–> 类或者接口类型. 它也可以拥有泛型参数,如 java.util.Set

public interface DeclaredType extends ReferenceType {

    /**
     * Returns the element corresponding to this type.
     * 返回该类型对应的element
     *
     * @return the element corresponding to this type
     */
    Element asElement();

    /**
     * Returns the type of the innermost enclosing instance or a
     * {@code NoType} of kind {@code NONE} if there is no enclosing
     * instance.  Only types corresponding to inner classes have an
     * enclosing instance.
     * 返回最内层包围实例的类型,如果没有包围实例则返回NoType和NONE对应的TypeMirror.
     * 只有对应于内部类的类型才有包围实例
     * 
     * @return a type mirror for the enclosing type
     * @jls 8.1.3 Inner Classes and Enclosing Instances
     * @jls 15.9.2 Determining Enclosing Instances
     */
    TypeMirror getEnclosingType();

    /**
     * Returns the actual type arguments of this type.
     * For a type nested within a parameterized type
     * (such as {@code Outer<String>.Inner<Number>}), only the type
     * arguments of the innermost type are included.
     * 返回该类型的泛型参数
     * 
     * @return the actual type arguments of this type, or an empty list
     *           if none
     */
    List<? extends TypeMirror> getTypeArguments();
}

NullType

代表null.代码如下:

public interface NullType extends ReferenceType {
}

WildcardType

代表一个通配符类型.包括:

(1)?
(2)? extends Number
(3)? super T
通配符的上界可通过extends 语句来进行设置,下界可通过super 来进行设置.代码如下:

public interface WildcardType extends TypeMirror {

    /**
     * Returns the upper bound of this wildcard.
     * If no upper bound is explicitly declared,
     * {@code null} is returned.
     * 返回该类型的上界,如果没有的话,则返回null
     *
     * @return the upper bound of this wildcard
     */
    TypeMirror getExtendsBound();

    /**
     * Returns the lower bound of this wildcard.
     * If no lower bound is explicitly declared,
     * {@code null} is returned.
     * 返回该类型的下界,如果没有的话,则返回null
     * @return the lower bound of this wildcard
     */
    TypeMirror getSuperBound();
}

javax.lang.model.util源码

Elements

操作java源程序元素的工具方法.

兼容性提醒:本类中的方法可能会在未来的版本中添加.

public interface Elements {

    /**
     * 返回指定全限定名所对应的PackageElement.如果指定的是"",则返回未命名包.如果没有找到对应的,则返回null.
     *
     */
    PackageElement getPackageElement(CharSequence name);

    /**
     * 返回指定规范名称对应的TypeElement,如果没有对应的,则返回null.
     *
     */
    TypeElement getTypeElement(CharSequence name);

    /**
     * 返回该注解的元素所对应的值,包括默认值
     */
    Map<? extends ExecutableElement, ? extends AnnotationValue>
            getElementValuesWithDefaults(AnnotationMirror a);

    /**
     * 返回该元素所对应的Javadoc.
     * 该元素对应的文档注释是有/**开头的,以*/结尾的,忽略空格。因此,文档注释包含至少三
     * 个“*”字符。文档注释返回的文本是在源代码中出现的注释的处理形式.开头的“/**”和结尾
     * 的“*/”被删除.对于在初始“/**”之后开始的注释行,前导空白字符将被丢弃,而在空白之后
     * 或开始该行时出现的任何连续的“*”字符也被丢弃。然后将处理后的行连接在一起(包括行终止符)并返回。
     */
    String getDocComment(Element e);

    /**
     * 如果指定的元素是deprecated,则返回true,否则,返回false.
     */
    boolean isDeprecated(Element e);

    /**
     * 返回指定元素所对应的二进制名称.
     * 关于这部分内容,可以参阅 JLS 13.1 二进制形式
     */
    Name getBinaryName(TypeElement type);


    /**
     * 返回指定元素所对应的包,如果指定的元素是包,则返回自己
     */
    PackageElement getPackageOf(Element type);

    /**
     * 返回指定元素的内部成员,包括继承和直接声明的.
     * 对于一个类来说,包含构造器,但是不包含本地或者匿名类
     * 请注意,某些类型的元素可以使用ElementFilter中的方法进行过滤。
     */
    List<? extends Element> getAllMembers(TypeElement type);

    /**
     * 返回该元素所对应的所有注解,不管是直接声明的还是继承的
     */
    List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e);

    /**
     * 如果第一个Element隐藏了第二个Element,则返回true
     */
    boolean hides(Element hider, Element hidden);

    /**
     * 测试第一个方法,作为制定类型的成员,复写了第二个方法
     * 当一个非抽象的方法复写了抽象的方法,这也叫实现.
     * 在最简单和最典型的用法中,类型参数的值只是含有复写方法的类或接口。举例:m1代表的是
     * String.hashCode,m2代表的是Object.hashCode.我们可以通过如下方式来测试是否String
     * 中的m1的方法复写了m2:
     * assert elements.overrides(m1, m2,
     *          elements.getTypeElement("java.lang.String")); 
     *  以下示例可说明更有趣的情况,其中类型A中的方法不重写类型B中的同名方法:
     *    class A { public void m() {} } }
            interface B { void m(); } }
            ...
            m1 = ...; // A.m 
            m2 = ...; // B.m 
            assert ! elements.overrides(m1, m2, elements.getTypeElement("A"));
      *  当有第三个类型c时,A中的方法就复写了B中的方法:       
      *  assert elements.overrides(m1, m2,
     *          elements.getTypeElement("C")); 
     */
    boolean overrides(ExecutableElement overrider, ExecutableElement overridden,
                      TypeElement type);

    /**
     * 返回表示原始类型值或字符串的常量表达式的文本。返回的文本格式适合于表示源代码中的值。
     * 参数value是 原始类型的值或者是String
     */
    String getConstantExpression(Object value);

    /**
     * 按指定的顺序将元素的表示打印到给定的Writer。这种方法的主要目的是用于诊断。未指定输出的确切格式,并有可能更改这种输出格式。
     */
    void printElements(java.io.Writer w, Element... elements);

    /**
     * 返回指定参数所对应的Name
     */
    Name getName(CharSequence cs);

    /**
     * 如果给定的类是函数接口,则返回true
     */
    boolean isFunctionalInterface(TypeElement type);
}

Types

操作类型的工具方法的接口

public interface Types {

    /**
     * 返回与类型对应的元素。类型可以是声明类型或类型变量。如果类型不是具有相应元素的类型,则返回null
     */
    Element asElement(TypeMirror t);

    /**
     * 测试是否2个对象代表的是同一个类型.
     * 警告:如果此方法的任何一个参数表示通配符,则此方法将返回false。因此,通配符不是与自
     * 身相同的类型。这可能首先令人惊讶,但一旦你认为这样的例子必须被编译器拒绝,才有意义:
     *    List<?> list = new ArrayList<Object>();
     *  list.add(list.get(0));
     *  由于注释仅是与类型相关联的元数据,所以在计算两个TypeMirror对象是否为相同类型时,
     *  不考虑两个参数上的注释集。特别地,两个类型的反射对象可以具有不同的注释,并且仍然被
     *  认为是相同的
     */
    boolean isSameType(TypeMirror t1, TypeMirror t2);

    /**
     * 测试是否第一个TypeMirror是第二个TypeMirror的子类型.任何类型都被认为是它自身的子类型
     */
    boolean isSubtype(TypeMirror t1, TypeMirror t2);

    /**
     * 测试一种类型是否可分配给另一种类型。 
     * 这部分的内容可以参考 JLS 5.2 Assignment Conversion
     */
    boolean isAssignable(TypeMirror t1, TypeMirror t2);

    /**
     * 如果第一个参数包含第二个参数则返回true
     */
    boolean contains(TypeMirror t1, TypeMirror t2);

    /**
     * 测试是否第一个参数是第二个参数的子签名
     */
    boolean isSubsignature(ExecutableType m1, ExecutableType m2);

    /**
     * 返回类型的直接超类型。接口类型(如果有的话)将出现在列表中的最后一个。
     */
    List<? extends TypeMirror> directSupertypes(TypeMirror t);

    /**
     * 返回指定类型擦除后的TypeMirror.  
     */
    TypeMirror erasure(TypeMirror t);

    /**
     * 返回指定类型的包装类型
     */
    TypeElement boxedClass(PrimitiveType p);

    /**
     * 返回指定包装类型所对应的原始类型
     */
    PrimitiveType unboxedType(TypeMirror t);

    /**
     * 对指定类型进行捕获转换
     */
    TypeMirror capture(TypeMirror t);

    /**
     * 返回指定TypeKind所对应的PrimitiveType
     */
    PrimitiveType getPrimitiveType(TypeKind kind);

    /**
     * 返回NullType-->代表null的类型
     */
    NullType getNullType();

    /**
     * 返回没有实际类型时使用的伪类型。返回的类型可以是TypeKind#VOID,也可以是TypeKind#NONE。对于包,使用 Elements.getPackageElement(CharSequence).asType()。
     */
    NoType getNoType(TypeKind kind);

    /**
     * 返回具有指定组件类型的数组类型.
     */
    ArrayType getArrayType(TypeMirror componentType);

    /**
     * 返回一个新的通配符类型参数。通配符的边界可以指定,或者两者都不,但不是两者都有。
     */
    WildcardType getWildcardType(TypeMirror extendsBound,
                                 TypeMirror superBound);

    /**
     * 返回与类型元素和实际类型参数相对应的类型。例如,给定Set的类型元素和String的TypeMirror
     * ,此方法可用于获得参数化类型Set<String>。
     * 类型参数的数目必须等于TypeElement的形式类型参数的数目,或者必须为零。如果为零,如
     * 果类型元素是泛型,则返回类型元素的原始类型
     * 如果正在返回参数化类型,则其类型元素不能包含在泛型外部类中。例如,参数化类型
     * Outer<String>.Inner<Number>,可以通过首先使用此方法获得类型Outer<String>,然
     * 后调用getDeclaredType(DeclaredType、TypeElement、TypeMirror)来构造。
     * 
     */
    DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs);

    /**
     * 返回与类型元素和实际类型参数相对应的类型,给定包含成员类型的成员类型。例如,可以通过
     * 首先使用getDeclaredType(TypeElement,TypeMirror)获得类型Outer<String>,然
     * 后调用此方法来构造参数化类型Outer<String>.Inner<Number>。
     * 如果包含的类型是参数化类型,则类型参数的数量必须等于typeElem的形式类型参数的数量。
     * 如果它不是参数化的,或者它是空的,那么这个方法就等同于getDeclaredType(typeElem, typeArgs)
     */
    DeclaredType getDeclaredType(DeclaredType containing,
                                 TypeElement typeElem, TypeMirror... typeArgs);

    /**
     * 当元素被视为给定类型的成员或直接包含时,返回元素的类型。
     * 当第一个参数是Set<String>,第二个参数是Set.add方法时,则返回一个参数为String的ExecutableType
     */
    TypeMirror asMemberOf(DeclaredType containing, Element element);
}

接下来我们来看一下AbstractTypeVisitor6的继承结构中涉及到的类或接口,如图:
在这里插入图片描述

AbstractTypeVisitor6

具有默认行为的类型的访问者,适用于jdk 1.6.

警告:该类实现的Type EvestIdor接口可能会在将来添加一些方法,以适应添加到Java编程语言未来版本的新的、目前未知的语言结构。因此,名称以“visit”开头的方法将来可能会被添加到这个类中;为了避免不兼容,扩展这个类的类不应声明任何以“visit”开头的实例方法。

当添加了这种新的访问方法时,此类中的默认实现将调用visitUnknown方法。还将引入一个新的抽象类型访问者类来对应新版本的语言;该访问者中的访问方法具有不同的默认行为。当新访问者被引入时,该类中的一部分或者全部都将被废弃.

注意,在访问者界面中添加一个新的访问方法的默认实现,而不是直接在访问者界面中添加一个默认方法,因为Java SE 8语言特征不能用于这个版本的API,因为这个版本需要在Java SE 7上运行。仅在Java SE 8和以后运行的API的未来版本可能会在这种情况下利用默认方法。

泛型参数 R –> 该visit方法的返回值类型
泛型参数 P –> visit方法额外添加的参数

public abstract class AbstractTypeVisitor6<R, P> implements TypeVisitor<R, P> {

    protected AbstractTypeVisitor6() {}


    public final R visit(TypeMirror t, P p) {
        return t.accept(this, p);
    }


    public final R visit(TypeMirror t) {
        return t.accept(this, null);
    }


    public R visitUnion(UnionType t, P p) {
        return visitUnknown(t, p);
    }


    public R visitIntersection(IntersectionType t, P p) {
        return visitUnknown(t, p);
    }


    public R visitUnknown(TypeMirror t, P p) {
        throw new UnknownTypeException(t, p);
    }
}

AbstractTypeVisitor7

用于jdk1.7的type visitor。

public abstract class AbstractTypeVisitor7<R, P> extends AbstractTypeVisitor6<R, P> {

    protected AbstractTypeVisitor7() {
        super();
    }

    public abstract R visitUnion(UnionType t, P p);
}

AbstractTypeVisitor8

用于jdk1.8的type visitor。

public abstract class AbstractTypeVisitor8<R, P> extends AbstractTypeVisitor7<R, P> {
   protected AbstractTypeVisitor8() {
        super();
    }

   public abstract R visitIntersection(IntersectionType t, P p);
}

SimpleElementVisitor6

对应jdk1.6的简单的visitor.

当visit方法是与jdk1.6的语法结构相关的,则会调用defaultAction方法.对应在jdk1.7或者之后的语法结构,则调用visitUnknown方法.

@SupportedSourceVersion(RELEASE_6)
public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
    /**
     * defaultAction 方法默认的返回值
     */
    protected final R DEFAULT_VALUE;


    protected SimpleElementVisitor6(){
        DEFAULT_VALUE = null;
    }


    protected SimpleElementVisitor6(R defaultValue){
        DEFAULT_VALUE = defaultValue;
    }

    protected R defaultAction(Element e, P p) {
        return DEFAULT_VALUE;
    }


    public R visitPackage(PackageElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitType(TypeElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitVariable(VariableElement e, P p) {
        // 如果VariableElement的种类不是RESOURCE_VARIABLE,则调用defaultAction方法,
        // ElementKind.RESOURCE_VARIABLE 对应jdk1.7的资源变量
        if (e.getKind() != ElementKind.RESOURCE_VARIABLE)
            return defaultAction(e, p);
        else
            return visitUnknown(e, p);
    }


    public R visitExecutable(ExecutableElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitTypeParameter(TypeParameterElement e, P p) {
        return defaultAction(e, p);
    }
}

SimpleElementVisitor7

对应jdk1.7的简单的visitor.

当visit方法是与jdk1.7和之前版本的语法结构相关的,则会调用defaultAction方法.

@SupportedSourceVersion(RELEASE_7)
public class SimpleElementVisitor7<R, P> extends SimpleElementVisitor6<R, P> {

    protected SimpleElementVisitor7(){
        super(null);
    }


    protected SimpleElementVisitor7(R defaultValue){
        super(defaultValue);
    }


    // 可以看到在SimpleElementVisitor6还需判断是否是jdk1.7中的ElementKind.RESOURCE_VARIABLE,在这里就直接调用defaultAction了.
    @Override
    public R visitVariable(VariableElement e, P p) {
        return defaultAction(e, p);
    }
}

SimpleElementVisitor8

对应jdk1.7的简单的visitor.

当visit方法是与jdk1.7和之前版本的语法结构相关的,则会调用defaultAction方法.

@SupportedSourceVersion(RELEASE_8)
public class SimpleElementVisitor8<R, P> extends SimpleElementVisitor7<R, P> {

    protected SimpleElementVisitor8(){
        super(null);
    }


    protected SimpleElementVisitor8(R defaultValue){
        super(defaultValue);
    }
}

TypeKindVisitor6

一个类型的Visitor,其默认行为适用于jdk1.6。对于可能具有多种类型的XYZ类型,该类中的visitXYZ方法委托给与第一个参数的类型相对应的visitXYZKind方法。visitXYZKind方法调用defaultAction方法,将它们的参数传递给defaultAction的相应参数。

@SupportedSourceVersion(RELEASE_6)
public class TypeKindVisitor6<R, P> extends SimpleTypeVisitor6<R, P> {

    protected TypeKindVisitor6() {
        super(null);
    }


    protected TypeKindVisitor6(R defaultValue) {
        super(defaultValue);
    }

    @Override
    public R visitPrimitive(PrimitiveType t, P p) {
        TypeKind k = t.getKind();
        switch (k) {
        case BOOLEAN:
            return visitPrimitiveAsBoolean(t, p);

        case BYTE:
            return visitPrimitiveAsByte(t, p);

        case SHORT:
            return visitPrimitiveAsShort(t, p);

        case INT:
            return visitPrimitiveAsInt(t, p);

        case LONG:
            return visitPrimitiveAsLong(t, p);

        case CHAR:
            return visitPrimitiveAsChar(t, p);

        case FLOAT:
            return visitPrimitiveAsFloat(t, p);

        case DOUBLE:
            return visitPrimitiveAsDouble(t, p);

        default:
            throw new AssertionError("Bad kind " + k + " for PrimitiveType" + t);
        }
    }

    public R visitPrimitiveAsBoolean(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    public R visitPrimitiveAsByte(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    public R visitPrimitiveAsShort(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    public R visitPrimitiveAsInt(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    public R visitPrimitiveAsLong(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    public R visitPrimitiveAsChar(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    public R visitPrimitiveAsFloat(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    public R visitPrimitiveAsDouble(PrimitiveType t, P p) {
        return defaultAction(t, p);
    }


    @Override
    public R visitNoType(NoType t, P p) {
        TypeKind k = t.getKind();
        switch (k) {
        case VOID:
            return visitNoTypeAsVoid(t, p);

        case PACKAGE:
            return visitNoTypeAsPackage(t, p);

        case NONE:
            return visitNoTypeAsNone(t, p);

        default:
            throw new AssertionError("Bad kind " + k + " for NoType" + t);
        }
    }


    public R visitNoTypeAsVoid(NoType t, P p) {
        return defaultAction(t, p);
    }


    public R visitNoTypeAsPackage(NoType t, P p) {
        return defaultAction(t, p);
    }


    public R visitNoTypeAsNone(NoType t, P p) {
        return defaultAction(t, p);
    }
}

TypeKindVisitor7

适用于jdk1.7的visitor.

@SupportedSourceVersion(RELEASE_7)
public class TypeKindVisitor7<R, P> extends TypeKindVisitor6<R, P> {


    protected TypeKindVisitor7() {
        super(null);
    }


    protected TypeKindVisitor7(R defaultValue) {
        super(defaultValue);
    }


    @Override
    public R visitUnion(UnionType t, P p) {
        return defaultAction(t, p);
    }
}

TypeKindVisitor8

适用于jdk1.8的visitor.

@SupportedSourceVersion(RELEASE_8)
public class TypeKindVisitor8<R, P> extends TypeKindVisitor7<R, P> {

    protected TypeKindVisitor8() {
        super(null);
    }


    protected TypeKindVisitor8(R defaultValue) {
        super(defaultValue);
    }


    @Override
    public R visitIntersection(IntersectionType t, P p) {
        return defaultAction(t, p);
    }
}

接下来看一下AbstractElementVisitor6的继承结构,如图
在这里插入图片描述

AbstractElementVisitor6

适用于jdk 1.6的Element Visitor.

@SupportedSourceVersion(RELEASE_6)
public abstract class AbstractElementVisitor6<R, P> implements ElementVisitor<R, P> {

    protected AbstractElementVisitor6(){}


    public final R visit(Element e, P p) {
        return e.accept(this, p);
    }


    public final R visit(Element e) {
        return e.accept(this, null);
    }


    public R visitUnknown(Element e, P p) {
        throw new UnknownElementException(e, p);
    }
}

AbstractElementVisitor7

适用于jdk 1.7的Element Visitor.

@SupportedSourceVersion(RELEASE_7)
public abstract class AbstractElementVisitor7<R, P> extends AbstractElementVisitor6<R, P> {
   protected AbstractElementVisitor7(){
        super();
    }
}

AbstractElementVisitor8

适用于jdk 1.8的Element Visitor.

@SupportedSourceVersion(RELEASE_8)
public abstract class AbstractElementVisitor8<R, P> extends AbstractElementVisitor7<R, P> {

    protected AbstractElementVisitor8(){
        super();
    }
}

ElementScanner6

一个具有默认行为的程序元素的Scanner,适用于jdk1.6。这个类中的visitXYZ方法通过调用对它们所包围的元素、参数等对应的scan方法来扫描它们的组件元素.子类可以通过覆盖visitXYZ方法来控制访问的顺序元素。注意,Scanner的客户端可以获得所期望的行为,即调用感兴趣的根对象上的v.scan(e, p)而不是v.visit(e, p).

当子类重写visitXYZ方法时,新方法通过调用super.visitXYZ来扫描其所包围的元素,具体访问者可以控制关于附加处理的组件元素遍历的顺序;例如,在重写方法开始时始终调用super.visitXYZ将产生先序遍历,等等。如果选用按照其他顺序进行遍历,则按照需要的顺序调用对应的visit方法,而不是适用
super.visitXYZ.

@SupportedSourceVersion(RELEASE_6)
public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {

    protected final R DEFAULT_VALUE;


    protected ElementScanner6(){
        DEFAULT_VALUE = null;
    }


    protected ElementScanner6(R defaultValue){
        DEFAULT_VALUE = defaultValue;
    }


    public final R scan(Iterable<? extends Element> iterable, P p) {
        R result = DEFAULT_VALUE;
        for(Element e : iterable)
            result = scan(e, p);
        return result;
    }


    public R scan(Element e, P p) {
        return e.accept(this, p);
    }


    public final R scan(Element e) {
        return scan(e, null);
    }


    public R visitPackage(PackageElement e, P p) {
        return scan(e.getEnclosedElements(), p);
    }


    public R visitType(TypeElement e, P p) {
        return scan(e.getEnclosedElements(), p);
    }


    public R visitVariable(VariableElement e, P p) {
        if (e.getKind() != ElementKind.RESOURCE_VARIABLE)
            return scan(e.getEnclosedElements(), p);
        else
            return visitUnknown(e, p);
    }


    public R visitExecutable(ExecutableElement e, P p) {
        return scan(e.getParameters(), p);
    }


    public R visitTypeParameter(TypeParameterElement e, P p) {
        return scan(e.getEnclosedElements(), p);
    }
}

ElementScanner7

适用于jdk1.7的 ElementScanner.

@SupportedSourceVersion(RELEASE_7)
public class ElementScanner7<R, P> extends ElementScanner6<R, P> {

    protected ElementScanner7(){
        super(null);
    }


    protected ElementScanner7(R defaultValue){
        super(defaultValue);
    }


    @Override
    public R visitVariable(VariableElement e, P p) {
        return scan(e.getEnclosedElements(), p);
    }
}

ElementScanner8

适用于jdk1.8的 ElementScanner.

@SupportedSourceVersion(RELEASE_8)
public class ElementScanner8<R, P> extends ElementScanner7<R, P> {

    protected ElementScanner8(){
        super(null);
    }


    protected ElementScanner8(R defaultValue){
        super(defaultValue);
    }
}

ElementKindVisitor6

程序元素类型的 visitor,适用于jdk1.6.

@SupportedSourceVersion(RELEASE_6)
public class ElementKindVisitor6<R, P>
                  extends SimpleElementVisitor6<R, P> {

    protected ElementKindVisitor6() {
        super(null);
    }


    protected ElementKindVisitor6(R defaultValue) {
        super(defaultValue);
    }


    @Override
    public R visitPackage(PackageElement e, P p) {
        assert e.getKind() == PACKAGE: "Bad kind on PackageElement";
        return defaultAction(e, p);
    }


    @Override
    public R visitType(TypeElement e, P p) {
        ElementKind k = e.getKind();
        switch(k) {
        case ANNOTATION_TYPE:
            return visitTypeAsAnnotationType(e, p);

        case CLASS:
            return visitTypeAsClass(e, p);

        case ENUM:
            return visitTypeAsEnum(e, p);

        case INTERFACE:
            return visitTypeAsInterface(e, p);

        default:
            throw new AssertionError("Bad kind " + k + " for TypeElement" + e);
        }
    }


    public R visitTypeAsAnnotationType(TypeElement e, P p) {
        return defaultAction(e, p);
    }

    public R visitTypeAsClass(TypeElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitTypeAsEnum(TypeElement e, P p) {
        return defaultAction(e, p);
    }

    public R visitTypeAsInterface(TypeElement e, P p) {
        return defaultAction(e, p);
    }

    /**

    @Override
    public R visitVariable(VariableElement e, P p) {
        ElementKind k = e.getKind();
        switch(k) {
        case ENUM_CONSTANT:
            return visitVariableAsEnumConstant(e, p);

        case EXCEPTION_PARAMETER:
            return visitVariableAsExceptionParameter(e, p);

        case FIELD:
            return visitVariableAsField(e, p);

        case LOCAL_VARIABLE:
            return visitVariableAsLocalVariable(e, p);

        case PARAMETER:
            return visitVariableAsParameter(e, p);

        case RESOURCE_VARIABLE:
            return visitVariableAsResourceVariable(e, p);

        default:
            throw new AssertionError("Bad kind " + k + " for VariableElement" + e);
        }
    }


    public R visitVariableAsEnumConstant(VariableElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitVariableAsExceptionParameter(VariableElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitVariableAsField(VariableElement e, P p) {
        return defaultAction(e, p);
    }

    public R visitVariableAsLocalVariable(VariableElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitVariableAsParameter(VariableElement e, P p) {
        return defaultAction(e, p);
    }

        public R visitVariableAsResourceVariable(VariableElement e, P p) {
        return visitUnknown(e, p);
    }

        @Override
    public R visitExecutable(ExecutableElement e, P p) {
        ElementKind k = e.getKind();
        switch(k) {
        case CONSTRUCTOR:
            return visitExecutableAsConstructor(e, p);

        case INSTANCE_INIT:
            return visitExecutableAsInstanceInit(e, p);

        case METHOD:
            return visitExecutableAsMethod(e, p);

        case STATIC_INIT:
            return visitExecutableAsStaticInit(e, p);

        default:
            throw new AssertionError("Bad kind " + k + " for ExecutableElement" + e);
        }
    }


    public R visitExecutableAsConstructor(ExecutableElement e, P p) {
        return defaultAction(e, p);
    }

    public R visitExecutableAsInstanceInit(ExecutableElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitExecutableAsMethod(ExecutableElement e, P p) {
        return defaultAction(e, p);
    }


    public R visitExecutableAsStaticInit(ExecutableElement e, P p) {
        return defaultAction(e, p);
    }



    @Override
    public R visitTypeParameter(TypeParameterElement e, P p) {
        assert e.getKind() == TYPE_PARAMETER: "Bad kind on TypeParameterElement";
        return defaultAction(e, p);
    }
}

ElementKindVisitor7

程序元素类型的 visitor,适用于jdk1.7.

@SupportedSourceVersion(RELEASE_7)
public class ElementKindVisitor7<R, P> extends ElementKindVisitor6<R, P> {

    protected ElementKindVisitor7() {
        super(null);
    }


    protected ElementKindVisitor7(R defaultValue) {
        super(defaultValue);
    }


    @Override
    public R visitVariableAsResourceVariable(VariableElement e, P p) {
        return defaultAction(e, p);
    }
}

ElementKindVisitor8

程序元素类型的 visitor,适用于jdk1.8.

@SupportedSourceVersion(RELEASE_8)
public class ElementKindVisitor8<R, P> extends ElementKindVisitor7<R, P> {

    protected ElementKindVisitor8() {
        super(null);
    }


    protected ElementKindVisitor8(R defaultValue) {
        super(defaultValue);
    }
}

接下来我们来看下AbstractAnnotationValueVisitor6的继承结构,如图:

在这里插入图片描述

AbstractAnnotationValueVisitor6

注解值的visitor,用于jdk 1.6

@SupportedSourceVersion(RELEASE_6)
public abstract class AbstractAnnotationValueVisitor6<R, P>
    implements AnnotationValueVisitor<R, P> {


    protected AbstractAnnotationValueVisitor6() {}

    public final R visit(AnnotationValue av, P p) {
        return av.accept(this, p);
    }


    public final R visit(AnnotationValue av) {
        return av.accept(this, null);
    }

    public R visitUnknown(AnnotationValue av, P p) {
        throw new UnknownAnnotationValueException(av, p);
    }
}

AbstractAnnotationValueVisitor7

注解值的visitor,用于jdk 1.7

@SupportedSourceVersion(RELEASE_7)
public abstract class AbstractAnnotationValueVisitor7<R, P> extends AbstractAnnotationValueVisitor6<R, P> {


    protected AbstractAnnotationValueVisitor7() {
        super();
    }
}

AbstractAnnotationValueVisitor8

注解值的visitor,用于jdk 1.8

@SupportedSourceVersion(RELEASE_8)
public abstract class AbstractAnnotationValueVisitor8<R, P> extends AbstractAnnotationValueVisitor7<R, P> {

    /**
     * Constructor for concrete subclasses to call.
     */
    protected AbstractAnnotationValueVisitor8() {
        super();
    }
}

SimpleAnnotationValueVisitor6

针对jdk 1.6的注解值的visitor。所有的visit方法都会调用defaultAction方法.

@SupportedSourceVersion(RELEASE_6)
public class SimpleAnnotationValueVisitor6<R, P>
    extends AbstractAnnotationValueVisitor6<R, P> {

    protected final R DEFAULT_VALUE;


    protected SimpleAnnotationValueVisitor6() {
        super();
        DEFAULT_VALUE = null;
    }


    protected SimpleAnnotationValueVisitor6(R defaultValue) {
        super();
        DEFAULT_VALUE = defaultValue;
    }


    protected R defaultAction(Object o, P p) {
        return DEFAULT_VALUE;
    }


    public R visitBoolean(boolean b, P p) {
        return defaultAction(b, p);
    }


    public R visitByte(byte b, P p) {
        return defaultAction(b, p);
    }


    public R visitChar(char c, P p) {
        return defaultAction(c, p);
    }

        public R visitDouble(double d, P p) {
        return defaultAction(d, p);
    }


    public R visitFloat(float f, P p) {
        return defaultAction(f, p);
    }


    public R visitInt(int i, P p) {
        return defaultAction(i, p);
    }

        public R visitLong(long i, P p) {
        return defaultAction(i, p);
    }


    public R visitShort(short s, P p) {
        return defaultAction(s, p);
    }

       public R visitString(String s, P p) {
        return defaultAction(s, p);
    }


    public R visitType(TypeMirror t, P p) {
        return defaultAction(t, p);
    }


    public R visitEnumConstant(VariableElement c, P p) {
        return defaultAction(c, p);
    }


    public R visitAnnotation(AnnotationMirror a, P p) {
        return defaultAction(a, p);
    }

    public R visitArray(List<? extends AnnotationValue> vals, P p) {
        return defaultAction(vals, p);
    }
}

SimpleAnnotationValueVisitor7

针对jdk 1.7的注解值的visitor。所有的visit方法都会调用defaultAction方法.

@SupportedSourceVersion(RELEASE_7)
public class SimpleAnnotationValueVisitor7<R, P> extends SimpleAnnotationValueVisitor6<R, P> {

    protected SimpleAnnotationValueVisitor7() {
        super(null);
    }


    protected SimpleAnnotationValueVisitor7(R defaultValue) {
        super(defaultValue);
    }
}

SimpleAnnotationValueVisitor8

针对jdk 1.8的注解值的visitor。

@SupportedSourceVersion(RELEASE_8)
public class SimpleAnnotationValueVisitor8<R, P> extends SimpleAnnotationValueVisitor7<R, P> {

    protected SimpleAnnotationValueVisitor8() {
        super(null);
    }


    protected SimpleAnnotationValueVisitor8(R defaultValue) {
        super(defaultValue);
    }
}

ElementFilter

过滤器,用于从元素集合中选择感兴趣元素。返回的集合和列表是新集合,并使用该参数作为后备存储。该类中的方法不保证防止参数的并发修改。返回的集合和列表是可变的,但对于并发访问来说是不安全的。返回集具有与方法的参数相同的迭代顺序。

如果将包含NULL的迭代项和集合作为参数传递给该类中的方法,则将引发NullPointerException异常。

注意,静态导入语句可以使对该类中的方法的调用文本更加简洁;举例:

import static javax.lang.model.util.ElementFilter.*;
     ...
List<VariableElement> fs = fieldsIn(someClass.getEnclosedElements());

代码如下:

public class ElementFilter {
    private ElementFilter() {} // Do not instantiate.

    private static final Set<ElementKind> CONSTRUCTOR_KIND =
        Collections.unmodifiableSet(EnumSet.of(ElementKind.CONSTRUCTOR));

    private static final Set<ElementKind> FIELD_KINDS =
        Collections.unmodifiableSet(EnumSet.of(ElementKind.FIELD,
                                               ElementKind.ENUM_CONSTANT));
    private static final Set<ElementKind> METHOD_KIND =
        Collections.unmodifiableSet(EnumSet.of(ElementKind.METHOD));

    private static final Set<ElementKind> PACKAGE_KIND =
        Collections.unmodifiableSet(EnumSet.of(ElementKind.PACKAGE));

    private static final Set<ElementKind> TYPE_KINDS =
        Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS,
                                               ElementKind.ENUM,
                                               ElementKind.INTERFACE,
                                               ElementKind.ANNOTATION_TYPE));

    public static List<VariableElement>
            fieldsIn(Iterable<? extends Element> elements) {
        return listFilter(elements, FIELD_KINDS, VariableElement.class);
    }


    public static Set<VariableElement>
            fieldsIn(Set<? extends Element> elements) {
        return setFilter(elements, FIELD_KINDS, VariableElement.class);
    }


    public static List<ExecutableElement>
            constructorsIn(Iterable<? extends Element> elements) {
        return listFilter(elements, CONSTRUCTOR_KIND, ExecutableElement.class);
    }


    public static Set<ExecutableElement>
            constructorsIn(Set<? extends Element> elements) {
        return setFilter(elements, CONSTRUCTOR_KIND, ExecutableElement.class);
    }


    public static List<ExecutableElement>
            methodsIn(Iterable<? extends Element> elements) {
        return listFilter(elements, METHOD_KIND, ExecutableElement.class);
    }


    public static Set<ExecutableElement>
            methodsIn(Set<? extends Element> elements) {
        return setFilter(elements, METHOD_KIND, ExecutableElement.class);
    }


    public static List<TypeElement>
            typesIn(Iterable<? extends Element> elements) {
        return listFilter(elements, TYPE_KINDS, TypeElement.class);
    }

    /**

    public static Set<TypeElement>
            typesIn(Set<? extends Element> elements) {
        return setFilter(elements, TYPE_KINDS, TypeElement.class);
    }

   public static List<PackageElement>
            packagesIn(Iterable<? extends Element> elements) {
        return listFilter(elements, PACKAGE_KIND, PackageElement.class);
    }


    public static Set<PackageElement>
            packagesIn(Set<? extends Element> elements) {
        return setFilter(elements, PACKAGE_KIND, PackageElement.class);
    }

    // Assumes targetKinds and E are sensible.
    private static <E extends Element> List<E> listFilter(Iterable<? extends Element> elements,
                                                          Set<ElementKind> targetKinds,
                                                          Class<E> clazz) {
        List<E> list = new ArrayList<E>();
        for (Element e : elements) {
            if (targetKinds.contains(e.getKind()))
                list.add(clazz.cast(e));
        }
        return list;
    }

    // Assumes targetKinds and E are sensible.
    private static <E extends Element> Set<E> setFilter(Set<? extends Element> elements,
                                                        Set<ElementKind> targetKinds,
                                                        Class<E> clazz) {
        // Return set preserving iteration order of input set.
        Set<E> set = new LinkedHashSet<E>();
        for (Element e : elements) {
            if (targetKinds.contains(e.getKind()))
                set.add(clazz.cast(e));
        }
        return set;
    }
}

总体说来,该类首先声明了5个set,分别对应构造器,字段,方法,包,类型.然后针对这5种类型的过滤分别声明了2种类型的api,一种是针对Iterable,一种是针对Set.方法的实现还是比较简单的…属于一看就懂的…

参考:
https://blog.csdn.net/qq_26000415/article/details/82352764
https://blog.csdn.net/weixin_56442629/article/details/115430210
https://www.cnblogs.com/szbm/p/15771076.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值