Why is it not possible to extend annotations in Ja

2019-01-01 06:30发布

I don't understand why there is no inheritance in Java annotations, just as Java classes. I think it would be very useful.

For example: I want to know if a given annotation is a validator. With inheritance, I could reflexively navigate through superclasses to know if this annotation extends a ValidatorAnnotation. Otherwise, how can I achieve this?

So, can anyone give me a reason for this design decision?

8条回答
不再属于我。
2楼-- · 2019-01-01 07:14

In a sense you already have it with Annotations - meta Annotations. If you annotate an annotation with meta information, that is in many ways equivalent to extending an additional interface. Annotations are interfaces, so polymorphism doesn't really come into play, and since they are static in nature, there can be no runtime dynamic dispatching.

In your validator example, you could just on the annotation get the annotated type and see if it has a validator meta-annotation.

The only use case I could see that inheritance would help is if you wanted to be able to get the annotation by super type, but that would add a whole bunch of complexity, because a given method or type may have two such annotations on it, meaning that an array would have to be returned instead of just a single object.

So I think the ultimate answer is that the use cases are esoteric and complicate more standard use cases making it not worth it.

查看更多
墨雨无痕
3楼-- · 2019-01-01 07:15

I might be three years late in responding to this question, but I found it interesting because I found myself in the same spot. Here's my take on it. You can view annotations as Enums. They provide a one-way kind of information - use it or lose it.

I had a situation where I wanted to simulate GET, POST, PUT and DELETE in a web-app. I so badly wanted to have a "super" annotation that was called "HTTP_METHOD". It later on dawned on me that it didn't matter. Well, I had to settle with using a hidden field in the HTML form to identify DELETE and PUT (because POST and GET were available anyway).

On the server-side, I looked out for a hidden request parameter with the name, "_method". If the value was PUT or DELETE, then it overrode the associated HTTP request method. Having said that, it didn't matter whether or not I needed to extend an annotation to get the work done. All the annotations looked the same, but they were treated differently on the server side.

So in your case, drop the itch to extend annotations. Treat them as 'markers'. They "represent" some information, and not necessarily "manipulate" some information.

查看更多
余生无你
4楼-- · 2019-01-01 07:17

One thing I could think of is the possibility to have multiple annotations. So you could add validator and a more specific annotation at the same place. But I could be mistaken :)

查看更多
何处买醉
5楼-- · 2019-01-01 07:21

Never thought about that but... seems that you're right, there is no problem with annotations inheritance facility (at least I don't see the problem with it).

About your example with 'validator' annotation - you can exploit 'meta-annotation' approach then. I.e. you apply particular meta-annotation to the whole annotation interface.

查看更多
与君花间醉酒
6楼-- · 2019-01-01 07:21

the same problem I have. No, you can't. I did 'disciplined' myself to write properties in annotations to respect some standards, so outside when you get annotation you can 'sniff' what kind od annotation it is by properties it has.

查看更多
孤独总比滥情好
7楼-- · 2019-01-01 07:23

About the reason why it wasn't designed that way you can find the answer in the JSR 175 Design FAQ, where it says:

Why don’t you support annotation subtyping (where one annotation type extends another)?

It complicates the annotation type system, and makes it much more difficult to write “Specific Tools”.

“Specific Tools” — Programs that query known annotation types of arbitrary external programs. Stub generators, for example, fall into this category. These programs will read annotated classes without loading them into the virtual machine, but will load annotation interfaces.

So, yes I guess, the reason is it just KISS. Anyway, it seems this issue (along with many others) are being looked into as part of JSR 308, and you can even find an alternative compiler with this functionality already developed by Mathias Ricken.

查看更多
登录 后发表回答