带有类型参数的注解属性 [英] Annotation attributes with type parameters

查看:22
本文介绍了带有类型参数的注解属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When you define a Java interface, it's possible to declare a method with type parameters, for example like this:

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

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

The same thing does not work in an annotation. This, for example, is illegal:

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

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

I can get what I'm after by using the raw type Enum:

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

不能用类型参数声明注解属性的具体原因是什么?

What exactly is the reason why it is not possible to declare annotation attributes with type parameters?

推荐答案

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

I think it is possible, but it requires lots of additions to language spec, which is not justified.

首先,对于枚举示例,您可以使用 Class.

First, for you enum example, you could use Class<? extends Enum<?>> options.

Class<还有一个问题?扩展枚举>options:因为 Enum.class 是一个 Class,它是一个 Classoptions=Enum.class

There is another problem in Class<? extends Enum> options: since Enum.class is a Class<Enum> which is a Class<? extends Enum>, it's legal to options=Enum.class

Class,因为 Enum 不是 Enum 的子类型,这是凌乱的原始类型处理中相当偶然的事实.

That can't happen with Class<? extends Enum<?>> options, because Enum is not a subtype of Enum<?>, a rather accidental fact in the messy raw type treatments.

回到一般问题.由于在有限的属性类型中,Class 是唯一带有类型参数的类型,并且通配符通常具有足够的表达能力,因此您的担忧不是很值得解决.

Back to the general problem. Since among limited attribute types, Class is the only one with a type parameter, and wildcard usually is expressive enough, your concern isn't very much worth addressing.

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

Let's generalize the problem even further, suppose there are more attribute types, and wildcard isn't powerful enough in many cases. For example, let's say Map is allowed, e.g.

Map<String,Integer> options();

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

假设我们想要一个属性类型为 Map 对于任何类型 x.这不能用通配符表示 - Map 意味着 Map 对于任何 x,y.

Suppose we want an attrbite type to be Map<x,x> for any type x. That can't be expressed with wildcards - Map<?,?> means rather Map<x,y> for any x,y.

一种方法是允许类型的类型参数:Map.这实际上在一般情况下非常有用.但这是对类型系统的重大改变.

One approach is to allow type parameters for a type: <X>Map<X,X>. This is actually quite useful in general. But it's a major change to type system.

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

Another approach is to reinterpret type parameters for methods in an annotation type.

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

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

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

this doesn't work at all in the current understanding of method type parameters, inference rules, inheritance rules etc. We need to change/add a lot of things to make it work.

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

In either approaches, it's a problem how to deliver X to annotation processors. We'll have to invent some additional mechanism to carry type arguments with instances.

这篇关于带有类型参数的注解属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆