如何只允许 类 在 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 编译器而没有任何其他工具),但它没有回答这个关于使用注释的问题。
假设我有注释 @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 编译器而没有任何其他工具),但它没有回答这个关于使用注释的问题。