java - 带有类型参数的注解属性

标签 java generics annotations

当你定义一个 Java 接口(interface)时,可以声明一个带有类型参数的方法,例如这样:

public interface ExampleInterface {
    <E extends Enum<E>> Class<E> options();
}

同样的事情在注释中不起作用。例如,这是非法的:

public @interface ExampleAnnotation {
    <E extends Enum<E>> Class<E> options();
}

我可以通过使用原始类型 Enum 得到我想要的:

public @interface ExampleAnnotation {
    @SuppressWarnings("rawtypes")
    Class<? extends Enum> options();
}

究竟是什么原因不能用类型参数声明注解属性?

最佳答案

我认为这是可能的,但它需要对语言规范进行大量添加,这是不合理的。

首先,对于您的枚举示例,您可以使用 Class<? extends Enum<?>> options .

Class<? extends Enum> options 还有一个问题: 自 Enum.classClass<Enum>这是 Class<? extends Enum> , options=Enum.class 是合法的

Class<? extends Enum<?>> options 不会发生这种情况, 因为 Enum不是 Enum<?> 的子类型,在凌乱的原始类型处理中是一个相当偶然的事实。

回到一般问题。由于在有限的属性类型中,Class是唯一一个有类型参数的,通配符通常足够表达,你的问题不是很值得解决。

让我们进一步概括这个问题,假设属性类型更多,而通配符在很多情况下都不够强大。例如,假设 Map是允许的,例如

Map<String,Integer> options();

options={"a":1, "b":2} // suppose we have "map literal"

假设我们希望属性类型为 Map<x,x>对于任何类型x .这不能用通配符表示 - Map<?,?>意思是Map<x,y>对于任何 x,y .

一种方法是允许类型的类型参数:<X>Map<X,X> .一般来说,这实际上非常有用。但这是对类型系统的重大改变。

另一种方法是重新解释注释类型中方法的类型参数。

<X> Map<X,X> options();

options={ "a":"a", "b":"b" }  // infer X=String

这在目前对方法类型参数、推理规则、继承规则等的理解中根本不起作用。我们需要更改/添加很多东西才能使其起作用。

在任何一种方法中,如何交付 X 都是一个问题。到注释处理器。我们必须发明一些额外的机制来为实例携带类型参数。

关于java - 带有类型参数的注解属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7594582/

相关文章:

c# - 如何将 repository<T> 中的泛型 T 转换为接口(interface)以在 LINQ to SQL 过滤器中有条件地访问接口(interface)属性?

java - 泛型和性能问题

java - 如果客户端代码中使用了服务器包中的注释,GWT 会编译吗?

java - 关于注解的说明

java - 条目名称 'javax/annotation/CheckReturnValue.java' 碰撞生成调试 apk

java - 想列出内部存储和外部存储上的所有音乐文件,但在 Android 10 上无法完成

java - 在 Hibernate 中使用 PreUpdate 监听器时记录未更新

java - 如何使用 jwplayer android sdk 播放前置、中置和后置广告

java - Java 中的泛型和类型推断

java - 解析没有数据的 XML 标签。获取 NullPointerException