How can we make interface annotations be inherited by implementations? - java

When I have an Interface, for example:
public interface Model {
String toString();
}
And I want that every class that implements this Interface will use the following Annotations:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
So it will look like this in the Interface:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public interface Model {
String toString();
}
And a test class:
#XmlRootElement(name = "user")
public class User implements Model {
}
Something like this example doesn't work. How can I perform that, an abstract class with the annotations is maybe the solution?
Thank you in advance!

A class never inherits annotations from the interfaces it implements. Annotations that are so designated can be inherited from superclasses, but that's a characteristic of the annotation, and not the default. If the annotations you are trying to use happen to be inheritable in that way -- you'll have to check their documentation -- then you can cause them to be inherited by deriving all your model classes from a common, annotated, superclass.
Really, though, what's so bad about annotating each class explicitly? It's clearer, and no more verbose than implementing an interface.

Related

Annotation Inheritance in jersey

I'm creating some resource class with same form so a good idea is use DRY and use inheritance.
So I've create a RootResource class and put some methods there. I want to annotate them and then implement them in subclass but it doesn't work! Here is a sample code:
public abstract class RootResource {
#GET
#Path("/{id: .*}")
public abstract String getInfo(String uid);
}
#Path("/user")
public class UserResource extends RootResource{
public String getInfo(#PathParam("id") String uid) {
System.out.println("Hello!");
}
}
I'm using jersey 2.6.
Any Idea?
Thanks.
I've been through the same issue while using Jersey. The Java EE standard for JAX-RS states the following:
3.6 Annotation Inheritance
JAX-RS annotations MAY be used on the methods and method parameters of a > super-class or an implemented
interface. Such annotations are inherited by a corresponding sub-class
or implementation class method provided that method and its parameters
do not have any JAX-RS annotations of its own. Annotations on a
super-class take precedence over those on an implemented interface.
The precedence over conflicting annotations defined in multiple
implemented interfaces is implementation specific.
If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the super class or interface method are
ignored.
While Jersey as the reference implementation is very strict with this statement, Resteasy implementation is more lenient and did the trick for me.
It's important to specify the path over the class since it's the root resource class so the it will get where to look at the class loading and not for individual overridden methods:
#Path("/account/member/")
public class RootResource {
. . .

How to get annotations of interface or abstract class methods in Java

I have an interface like this:
public interface IFoo{
#AnnotationTest(param="test")
String invoke();
}
and I implement this like this:
public class Foo implements IFoo{
#Override
public String invoke(){
Method method = new Object() {
}.getClass().getEnclosingMethod();
AnnotationTest ann = method.getAnnotation(AnnotationTest.class);
if(ann == null){
System.out.printl("Parent method's annotation is unreachable...")
}
}
}
If it is possible to reach parent's annotation, I want to learn the way of it.
Any help or idea will be appreciated.
You can use Spring AnnotationUtils.findAnnotation to read annotations from interfaces.
Example :
Interface I.java
public interface I {
#SomeAnnotation
void theMethod();
}
Implementing class A.java
public class A implements I {
public void theMethod() {
Method method = new Object() {}.getClass().getEnclosingMethod();
SomeAnnotation ann = AnnotationUtils.findAnnotation(method, AnnotationTest.class);
}
}
It obviously requires to include in your project (and import) Spring framework classes.
There is no direct way to get it. If you really need, you have to manually loop over getInterfaces() to find if any implemented interface has the annotation. If you want to search for (eventually abstract) superclasses and the annotation is not #Inherited, you can again iterate the superclass chain until finding Object (*).
But beware, as following post states, there are good reasons for this not to be directly implemented in Java : Why java classes do not inherit annotations from implemented interfaces?
(*) If the annotation is #Inherited it is automatically searched on superclasses, but not on interfaces.
you can't inherit annotations.
But a framework that uses an annotation can check to see if annotation is present on superclass

annotating methods in implementation classes or interfaces?

I am using Java1.7 and spring3.
I have below classes.
MyInterface.java
public interface MyInterface{
String getResult();
}
MyInterfaceImpl.java
public class MyInterfaceImpl implements MyInterface{
#MyCustomAnnotation
public String getResult(){
//some logic
}
}
I annotated method in Impl class. Is it good practice to annotate methods in implementation class? Or do i need to annotate methods in the interface itself?
Thanks!
Classes don't inherit the annotation from interfaces, so you should be really careful using annotations on interfaces.
Here is an example of what can happen if you are not careful:
http://kim.saabye-pedersen.org/2013/05/spring-annotation-on-interface-or-class.html

Is there wildcard for annotatted classes

Persistent object:
#Entity
public class PersistentModelObject{
...
}
I need something like:
interface GenericDao<T annotated_with Entity>{
//crud
}
Or can it be simulated in some way (with extension, implementation, etc).
EDIT: Please someone who understands my question to edit it to some understandable level.
I dont think you can use annotations like that via generics, but you can use java.lang.Class java.lang.reflect.Field isAnnotationPresent(YourAnnotation.class) to check if a class is annotated with a certain annotation.
A better aproach might be using marker interfaces? Something like:
public class PersistentModelObject implements MyPersistableType{
...
}
and
interface MyPersistableType {} //marker interface
Then you may use it like this:
interface GenericDao<T extends MyPersistableType>{
//crud
}
But then again, it depends on what you are trying to solve.
This restriction can only be checked at runtime using reflection.

Add Java Annotation to inherited field

I'm working on something that might benefit from a pattern like the following:
public abstract class SomeBuisnessThingy()
{
protected int someDatapoint;
}
public class ADatabaseThingy() extends SomeBusinessThingy()
{
#SomeJPAAnnotation
???? someDatapoint;
}
public class AWebServiceThingy() extends SomeBusinessThingy()
{
#SomeSOAPStuff
???? someDatapoint;
}
It smells more like an interface than an abstract class, but the same thing needs to be done. I have a DB implementation of that class and a WS implementation of that class.
Those representations are very similar, but may be different. For example the WS class may expose a field as a String so a 3rd party can easily do an integration, it can also be splot into its own package so we can hand a customer some lightweight WebService or POJO classes without all the baggage of the DB or a JPA framework coming with it. Perhaps it could be used to create the basic classes needed for something then switch between persistence frameworks that use different annotations.
Is it possible to ADD annotations to inherited fields?
No. If you need to annotate inherited members, you need to annotate the methods, not the fields.

Categories

Resources