Why is it not possible to extend annotations in Java?
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.
How to extend annotations in Java?
This is not possible right now. But in the near future we will support plugins for AndroidAnnotations, so you will be able to add new annotations and corresponding code generators easily.
Is there something like Annotation Inheritance in java?
Unfortunately, no. Apparently it has something to do with programs that read the annotations on a class without loading them all the way. See Why is it not possible to extend annotations in Java?
However, types do inherit the annotations of their superclass if those annotations are @Inherited
.
Also, unless you need those methods to interact, you could just stack the annotations on your class:
@Move
@Page
public class myAwesomeClass {}
Is there some reason that wouldn't work for you?
Is class extends annotations of an other?
Annotations are not inherited.
You can read more here: http://fusionsoft-online.com/articles-java-annotations.php
Some other references:
https://stackoverflow.com/a/1644135/1001027
and
https://stackoverflow.com/a/4745820/1001027
Exceptions are annotations which its declaration is annotated with @Inherited.
Why java classes do not inherit annotations from implemented interfaces?
I'd say the reason is that otherwise a multiple-inheritance problem would occur.
Example:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Inherited
public @interface Baz { String value(); }
public interface Foo{
@Baz("baz") void doStuff();
}
public interface Bar{
@Baz("phleem") void doStuff();
}
public class Flipp{
@Baz("flopp") public void doStuff(){}
}
public class MyClass extends Flipp implements Foo, Bar{}
If I do this:
MyClass.class.getMethod("doStuff").getAnnotation(Baz.class).value()
what's the result going to be? 'baz', 'phleem' or 'flopp'?
For this reason, annotations on interfaces are rarely useful.
Why can @Repeatable Annotations not be inherited from interfaces
Please recall the documentation of @Inherited
:
If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type.
In other words, @Inherited
never was intended to be a feature for collecting multiple annotations on a type hierarchy. Instead, you will get the annotation of the most specific type which has an explicit annotation.
In other words, if you change your declaration to
@RepeatableAnnotation("FOO") @RepeatableAnnotation("BAR") class Base {}
@RepeatableAnnotation("C") @RepeatableAnnotation("D")
public class TestClass extends Base implements IntefaceA, IntefaceB {
it won’t change the result; FOO
and BAR
of Base
are not inherited by TestClass
as it has the explicit annotation values C
and D
.
Expanding this to the interface
hierarchy would be awkward due to the multiple inheritance and the fact that a super-interface may turn out to be a sub-interface of another super-interface so finding the most specific one is not trivial. This differs heavily from the linear search of the superclass hierarchy.
You may encounter the situation where multiple unrelated annotated interface
s exist but it’s not clear why this ambiguity should be resolved by joining them into one repeated annotation. This would not harmonize with the behavior in all other scenarios.
Note that the answer you have linked is a bit odd as it shows code using a method annotation but method annotations are never inherited, regardless of whether you specified @Inherited
or not (an audit tool should generate a warning when you combine @Target(ElementType.METHOD)
with @Inherited
, imho). @Inherited
is relevant for type annotations only.
How do you extend a Java class and change annotations?
Though I'm not sure why you'd want to, you'd need to extend the class, override the methods, and apply the annotations:
public class App
{
public static void main(String[] args) throws NoSuchMethodException
{
Class<MyClass> c = MyClass.class;
MyAnnotation a = c.getMethod("someMethod",null).getAnnotation(MyAnnotation.class);
System.out.println(a.name());
Class<MySubclass> c2 = MySubclass.class;
a = c2.getMethod("someMethod",null).getAnnotation(MyAnnotation.class);
System.out.println(a.name());
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
String name() default "";
}
class MyClass {
@MyAnnotation(name="Some value")
public String someMethod() {
return "Hi!";
}
}
class MySubclass extends MyClass {
@Override
@MyAnnotation(name="Some other value")
public String someMethod() {
return super.someMethod();
}
}
Output:
Some value
Some other value
Related Topics
Best Way to Compare 2 Xml Documents in Java
What's the Difference Between Softreference and Weakreference in Java
Using Pairs or 2-Tuples in Java
Initial Size for the Arraylist
In Java How to Sort One List Based on Another
How to Respond with an Http 400 Error in a Spring MVC @Responsebody Method Returning String
Gson Serialize a List of Polymorphic Objects
Why One Should Prefer Using CSS Over Xpath in Ie
Is System.Nanotime() Completely Useless
Comparing Java Enum Members: == or Equals()
How to Load Classes at Runtime from a Folder or Jar
Hibernate Opensession() VS Getcurrentsession()
What Is the Java's Internal Represention for String? Modified Utf-8? Utf-16