在java限定类型中使用注解tmesis/的目的是什么?

gywdnpxw  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(340)

这有目的吗 static @NotNull @Other My.@NotNull @Other Builder createBuilder() ```
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

public class A {
static class My {
static class Builder {
public My build() {
return new My(); } } }

@Target({ElementType.METHOD, ElementType.TYPE_USE})
public @interface NotNull { }

@Target({ElementType.METHOD, ElementType.TYPE_USE})
public @interface Other { }

public static @NotNull @Other My.@NotNull @Other Builder createBuilder() {
    return new My.Builder();
}

}

64jmpszr

64jmpszr1#

使用这种构造的主要原因是向后兼容性。
java之前 8,没有类型注解,因此方法注解通常用于实际描述方法的返回类型,如

@Target(ElementType.METHOD)
public @interface NotNull { }

@Target(ElementType.METHOD)
public @interface Other { }

public static @NotNull @Other My.Builder createBuilder() {
    return new My.Builder();
}

从java开始 8,您可以对返回类型本身进行注解,这是您通常会做的事情。但是为了支持仍在寻找方法注解的旧工具,可以保留
@Target METHOD . 对于由简单名称组成的返回类型,方法注解和返回类型注解的代码位置是相同的,因此您可以使用单个引用同时创建方法注解和返回类型注解,即。

@MethodAndTypeAnnotation ReturnType method() …

但是,对于限定名,语法是不同的,因为类型注解必须放在被注解元素的简单名称之前,即。

@Target(ElementType.TYPE_USE)
public @interface NotNull { }

@Target(ElementType.TYPE_USE)
public @interface Other { }

public static My.@NotNull @Other Builder createBuilder() {
    return new My.Builder();
}

对于纯类型注解,使用 public static @NotNull @Other My.Builder createBuilder() 将导致编译器错误,因为这将是一个注解尝试 My 它在这里仅用作限定符,而不是实际的类型用法。注意,如果 Builder 是内部类而不是嵌套类(即不是 static ),对外部类型进行注解是合法的,尽管这不太可能。
对你来说

@Target({ElementType.METHOD, ElementType.TYPE_USE})
public @interface NotNull { }

@Target({ElementType.METHOD, ElementType.TYPE_USE})
public @interface Other { }

//            method annotation    type annotation
public static @NotNull @Other   My.@NotNull @Other Builder createBuilder() {
    return new My.Builder();
}

这两个引用都需要对方法和返回类型进行注解。如前所述,如果 Builder 如果是一个内部类,则第一次出现时对外部类型进行注解是合法的,并且无论您是否愿意,它都会对其进行注解。
因此,一般来说,不建议将“type use”注解作用域与其他注解作用域混合使用,而是建议更新代码处理工具,对于实际是类型注解工作的任务,仍然需要方法或字段注解。
如前所述,对于简单的名称,可以立即对方法和返回类型进行注解,这在使用 import 声明。但这需要顶级类位于一个包中:

package example;

import example.A.My.Builder;

public class A {
    static class My {
        static class Builder {
            public My build() {
                return new My(); } } }

    @Target({ElementType.METHOD, ElementType.TYPE_USE})
    public @interface NotNull { }

    @Target({ElementType.METHOD, ElementType.TYPE_USE})
    public @interface Other { }

    public static @NotNull @Other Builder createBuilder() {
        return new My.Builder();
    }
}

相关问题