5

It says:

primitive

String

Class

an Enum

another Annotation

an array of any of the above

Only these types are legal to be as Annotation member, why can't a generic Enum be a member of Annotation?

For example :

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Param {

    Enum value();

}

This is not allowed. But Enum is a constant isn't it? As you are using @Param(XXX), filling in the Enum, the @Param(XXX) is decided (which means this is constant). Why is it only a specific enum allowed to be a member?

What I am trying to do is to make a Annotation that receives any enums:

// for example
@Param(value = AEnum.ABC)
@Param(value = BEnum.TTT)
@Param(value = CEnum.OOO)

I want all above to be legal.

Kim
  • 5,045
  • 6
  • 38
  • 60
  • I think because Enum and Enum are different types. – Mufanu Jan 22 '16 at 09:52
  • That's just language design, you just cannot. – Tagir Valeev Jan 22 '16 at 10:06
  • @Jesper: that doesn’t look like a duplicate. The other question is about **Class** values which just happen to be a `Class extends Enum>`, but that’s just coincidence. The other question would work for any other `Class extends Foo>` as well, whereas this question is about `enum` *instances* as annotation values. – Holger Jan 22 '16 at 13:38
  • @Holger that other question (that I asked myself, btw) is not just about `Class` values, it's about annotation properties with type parameters in general, which is the same question as is asked here. (Whether the parameterized type is `Class` or `Enum` or something else isn't relevant). Apparently the answer is: this is not allowed because it would lead to a lot of complexity that the Java language designers were not willing to take. – Jesper Jan 22 '16 at 13:50
  • @Jesper: but this question isn’t asking for type parameters at all. – Holger Jan 22 '16 at 14:22
  • 1
    @Holger Ok, I see... I've reopened it. Still the other question might be useful: http://stackoverflow.com/questions/7594582/annotation-attributes-with-type-parameters – Jesper Jan 22 '16 at 14:39

1 Answers1

1

While each enum type inherits from java.lang.Enum, the type Enum itself is not an enum type. Similarly, while every annotation type inherits from java.lang.annotation.Annotation, the type Annotation itself is not an annotation type.

There is no technical reason for this, in the class file, each actual value will contain a reference to its type. So it would be technical possible to declare an annotation attribute as Object and discover the types of the actual values dynamically, but that’s not allowed by the formal specification.

By the way, enum constants also are not compile-time constants. So while you can declare a compile-time constant like final String FOO = "some string"; and refer to it in an annotation like @Name(value=FOO), you can’t do the same with an enum constant. You can only refer to the constant as declared in the enum type itself like EnumType.NAME. This also is a consequence of how it is formally defined in the specification.

Holger
  • 285,553
  • 42
  • 434
  • 765