如何只允许 类 在 Java 的方法参数中使用某些注释进行注释?

How to allow only classes annotated with some annotation in method parameters in Java?

假设我有注释 @MyAnnotation 和两个 classes:

@MyAnnotation
class Foo {
}

class Bar {
}

和一些需要class作为参数的方法

someMethod(Class<?> klass)

是否可以将 someMethod 参数限制为仅使用 @MyAnnotation 注释的 classes?我的意思是:

someMethod(Foo.class) //Must work
someMethod(Bar.class) //Compiler error

如果是,该怎么做?

是的,这是可能的。

作为一般规则,如果 属性 使用注解表示,则需要使用注解处理器。

这是一个使用 Checker Framework.

的完整示例

文件SO61029446.java:

public class SO61029446 {
  void someMethod(Class<? extends @MyAnnotation Object> klass) {}

  void client() {
    someMethod(Foo.class); // Must work
    someMethod(Bar.class); // Compiler error
  }
}

@MyAnnotation
@SuppressWarnings("subtyping")
class Foo {}

class Bar {}

文件MyAnnotation.java:

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf(UnknownMyAnnotation.class)
@interface MyAnnotation {}

@DefaultQualifierInHierarchy
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf({})
@interface UnknownMyAnnotation {}

现在,运行这些命令(在安装 Checker Framework 之后):

javacheck MyAnnotation.java
javacheck -g SO61029446.java -processor org.checkerframework.common.subtyping.SubtypingChecker -Aquals=MyAnnotation,UnknownMyAnnotation SO61029446.java

第二个命令的输出是:

SO61029446.java:11: error: [argument.type.incompatible] incompatible types in argument.
    someMethod(Bar.class); // Compiler error
                  ^
  found   : @UnknownMyAnnotation Class<@UnknownMyAnnotation Bar>
  required: @UnknownMyAnnotation Class<? extends @MyAnnotation Object>

编译器已抱怨非法调用,但已按照您的要求允许合法调用。

一些注意事项:

  • javacheck命令如Checker Framework Manual中所述。
  • 有两个 javacheck 命令,因为第一个命令使第二个命令的 class 路径上的注释可用。
  • 可能不需要 Foo class 上的 @SuppressWarnings("subtyping") 注释,具体取决于您的实际代码。 (这是一个玩具示例。)
  • Slaw 的回答从第一句 "No, this is not possible." 开始,不正确。 Slaw 在没有注释的情况下解决问题的不同方法并不是一个坏方法(在某些方面它更好,因为它只使用 Java 编译器而没有任何其他工具),但它没有回答这个关于使用注释的问题。