繁体   English   中英

递归使用@Retention注释,怎么可能?

[英]Recursive usage of @Retention annotation , how is it possible?

在java中的@Retention注释的源代码中, @ Rettention在其定义中使用,如此可能。

即使RetentionPolicy设置为RUNTIME ,那么如何在它未准备好运行之前执行它。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

这不是真正的递归 它只不过是对“后来”后面的类分别接口的前向引用。 Java允许使用前向引用。 对此有各种限制(请参阅Java语言规范,例如第8.3.2.2节) - 但这些限制都不适用于此。

除此之外:请记住,这里没有特殊的编译步骤。 编译器只是为Retention接口创建一个普通的类文件。 但那时:编译器很可能拥有关于此接口的硬编码知识。 如果使用RetentionPolicy.SOURCE ,编译器将从编译的类文件中排除注释。 这意味着编译器必须进行某种检查(以确定是否注释了某些内容并启用了SOURCE策略)。

换句话说:编译器可能包含类似的内容

if (x instaceof Retention) ...

并且此代码存在于编译器中。 编译其他注释时,上述工作正常,但在编译Retention接口本身时也可以正常工作。

但关键信息是:没有递归,只是一个前向引用。 稍后定义使用的东西。

它不需要Retention类。 源代码首先转换为AST。 它只需要Retention的qualifield名称来获取注释值。 这是OpenJDK的代码

按类名定义Retention

// com.sun.tools.javac.code.Symtab
protected Symtab(Context context) throws CompletionFailure {
    ...
    retentionType = enterClass("java.lang.annotation.Retention");
    ...
}

使用com.sun.tools.javac.code.Type retentionType从AST获取RetentionPolicy (第4行syms.retentionType.tsym ):

// com.sun.tools.javac.code.Types
public RetentionPolicy getRetention(Attribute.Compound a) {
    RetentionPolicy vis = RetentionPolicy.CLASS; // the default
    Attribute.Compound c = a.type.tsym.attribute(syms.retentionType.tsym);
    if (c != null) {
        Attribute value = c.member(names.value);
        if (value != null && value instanceof Attribute.Enum) {
            Name levelName = ((Attribute.Enum)value).value.name;
            if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE;
            else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS;
            else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME;
            else ;// /* fail soft */ throw new AssertionError(levelName);
        }
    }
    return vis;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM