Can i make some annotation required in classes that implements my interface? - java

I have this interface:
public interface IDbTable extends Serializable
{
public int getId();
}
I need to obligate all the classes that implements IDbTable, to have an annotation "#DatabaseTable" and at least one field inside class that have "#DatabaseField".
The only way of implementing IDbTable needs to be like this:
#DatabaseTable(tableName = "Something")
public static class TestTable implements IDbTable
{
#DatabaseField
public int id;
public int getId()
{
return id;
}
}
Is this possible with interface or inheritance?
Today i have an unit test that scan all the classes and check this requirements. Is this a good practice?

You can't apply annotations to an interface that will be inherited by the implementing class, according to Java documentation: http://docs.oracle.com/javase/6/docs/api/java/lang/annotation/Inherited.html
Indicates that an annotation type is automatically 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. This process will be repeated until an annotation
for this type is found, or the top of the class hierarchy (Object) is
reached. If no superclass has an annotation for this type, then the
query will indicate that the class in question has no such annotation.
Note that this meta-annotation type has no effect if the annotated
type is used to annotate anything other than a class. Note also that
this meta-annotation only causes annotations to be inherited from
superclasses; annotations on implemented interfaces have no effect.

Why don't you use annotation processing, to check that the requiered annotation is present in your class when it is sent to your framework, or at build/deployment time.

Related

Java JPA - prevent usage of zero-argument constructor of Embedded ID class

I have some JPA class for persistance
#Entity
#Table(name = "TABLE_NAME")
public MyJPA
{
#EmbeddedId
private MyJpaPrimaryKey key;
#Column(name = "DATABASE_COLUMN")
private SomeType someData;
...
}
And the Class for the primary key
#Embeddable
public class MyJpaPrimaryKey
{
...
}
Both have constructors with all required fields and/or whatever is convenient.
Now, JPA forces some zero-argument constructors
The Java class for mapped type "MyJpa" must define a non-private zero-argument constructor
Embedded ID class (i.e. MyJpaPrimaryKey) should include a zero argument constructor
None of those zero-argument constructors are meant for explicit use. I understand that I can make MyJpa() { } package private, so JPA is happy, and no-one else will use it unintentionally. But MyJpaPrimaryKey() { } must be public.
How do I prevent someone from using the zero-argument constructor MyJpaPrimaryKey()? In case this is not possible, how to get a warning (or better error) if someone uses it? I can think of #Deprecated annotation, but this feels like misusing this annotation.

#inherited also make #Overrided methods values inherited the annotation?

i'm working with a lot of interface inherited and annotations lately and I have a doubt about #Inherited annotation. I know that by default java annotations are not inherited for subclasses and methods. Using the #Inherited annotation we can make the annotation be inherited by the subclasses.
But it also work with the annotated values in the method constructors?
For example:
#Inherited
#StringDef({ID_REAR, ID_FRONT})
#Retention(RetentionPolicy.SOURCE)
public #interface CustomId {
}
public interface Setting {
void update(#CustomId String myCustomId);
}
public class CustomSetting implements Setting{
#Override public void update(String myCustomId) {
}
}
In this case, will the method update from CustomSetting implement the annotation#CustomId for his contructor (String myCustomId) ?
As Jesper answer above, the API docs is very clear about it: The #Inherit annotation doesn't work with anything other than a class:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

How can I disallow to use my own annotation for all classes instead of classes implementing concrete interface

I have the following code. I need to allow usage of this annotation (CommandName) ONLY for classes-instances of ICommand interface. How can I do it?
#Retention(RetentionPolicy.RUNTIME) // Make this annotation accessible at runtime via reflection.
#Target({ElementType.TYPE}) // This annotation can only be applied to class methods.
public #interface CommandName {
String value();
}
In compile time, you cant do that. In runtime, just check the classes - which is annotated by CommandName annotation - if they are implementing the ICommand interface.

Java type level annotation and private member visibility

I'm trying to externalize the baseurl of a spring #Controller into a static String member of the controller class. If i do so i have to declare the member public - otherwise it will not be visible to the #RequestMapping annotation. I can't understand why - isn't the annotation part of the class?
Can someone explain why i am forced not to use private here?
Invalid:
#Controller
#RequestMapping(PendingApprovalsController.CONTROLLER_URL)
public class PendingApprovalsController {
private static final String CONTROLLER_URL = "/some/url";
...
}
Valid:
#Controller
#RequestMapping(PendingApprovalsController.CONTROLLER_URL)
public class PendingApprovalsController {
public static final String CONTROLLER_URL = "/some/url";
...
}
An annotation is an ordinary Java class itself. It can't see the members of an annotated class unless they are visible to it, using normal Java rules. Furthermore the existence of annotations may be used by other code at runtime to operate on the members of the annotated class; if those members are not visible, those operations can't be performed.
This page from the JDK documentation package talks about how to define custom annotations, and how to consume annotations applied in code, and it's enlightening in this regard. To define an annotation type, you do something like
public #interface Copyright {
String value();
}
Your custom annotation is defined as a special kind of Java interface; in user, the JVM supplies a runtime implementation as needed. But the key thing to note is how you use your custom annotation, for example:
Method m = ... // Get a java.lang.reflect.Method object from somewhere
if (m.hasAnnotation(Copyright.class)) ...
Note that here we refer to the class object of the annotation type, demonstrating that an annotation is compiled to a normal Java type.

How #Target(ElementType.ANNOTATION_TYPE) works

Java annotations are marked with a #Target annotation to declare possible joinpoints which can be decorated by that annotation. Values TYPE, FIELD, METHOD, etc. of the ElementType enum are clear and simply understandable.
Question
WHY to use #Target(ANNOTATION_TYPE) value? What are the annotated annotations good for? What is their contribution? Give me an explanation of an idea how it works and why I should use it. Some already existing and well-known example of its usage would be great too.
You can use an annotated annotation to create a meta-annotation, for example consider this usage of #Transactional in Spring:
/**
* Shortcut and more descriptive "alias" for {#code #Transactional(propagation = Propagation.MANDATORY)}.
*/
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Transactional(propagation = Propagation.MANDATORY)
public #interface RequiresExistingTransaction {
}
When you enable Spring to process the #Transactional annotation, it will look for classes and methods that carry #Transactional or any meta-annotation of it (an annotation that is annotated with #Transactional).
Anyway this was just one concrete example how one can make use of an annotated annotation. I guess it's mostly frameworks like Spring where it makes sense to use them.
Each annotation annotated by #Target(ElementType.ANNOTATION_TYPE) is called Meta-annotation. That means, you can define your own custom annotations that are an amalgamation of many annotations combined into one annotation to create composed annotations.
A good example from Android world is StringDef
Denotes that the annotated String element, represents a logical type and that its value should be one of the explicitly named constants.
#Retention(SOURCE)
#StringDef({POWER_SERVICE, WINDOW_SERVICE, LAYOUT_INFLATER_SERVICE})
public #interface ServicesName {}
public static final String POWER_SERVICE = "power";
public static final String WINDOW_SERVICE = "window";
public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
Code inspector will treat #ServicesName and #WeekDays in the same way as #StringDef.
As a result we can create as much named StringDef's as we need and override set of constants. #Target(ElementType.ANNOTATION_TYPE) it is a tool that allows to extend the use of annotations.
Annotation is defined like a ordinary Java interface, but with an '#' preceding the interface keyword (i.e., #interface ). Annotations are used to provide supplemental information about a program. On the other hand, an interface can be defined as a container that stores the signatures of the methods to be implemented in the code segment.
WHY to use #Target(ANNOTATION_TYPE) value?
When there is need to apply an annotation to an another annotation. If you look at the source codes of the common Java annotations, you see often this code pattern:
#Target(ANNOTATION_TYPE)
public #interface TheAnnotation
{
...
}
For example,
#Documented
#Target({ ANNOTATION_TYPE })
#Retention(RUNTIME)
public #interface Constraint {
public Class<? extends ConstraintValidator<?, ?>>[] validatedBy();
}
What are the annotated annotations good for?
They are good or more precisely necessary if they are used to annotate other annotations.
What is their contribution?
They make possible to apply an annotation directly to an another annotation, that is a different thing than applying an annotation to a standard Java class or to method and so on.
Give me an explanation of an idea how it works and why I should use it.
For example, if you create a data model class and you may want that the program checks data validity. In that case, there might be need to create a new annotation and apply another annotations to this annotation. It is simple to add some data validity checks to this model by adding annotations to the class. For example, to check that some value is not null (#notNull) or email is valid (#ValidEmail) or length of a field is more than x characters (#Size). However, it is possible that there is not built in Java annotations for all purposes. For example, it is so if you liked to check if password and its matchingPassword are same. This is possible by creating the annotation class PasswordMatches:
#Target({TYPE})
#Retention(RUNTIME)
#Constraint(validatedBy = PasswordMatchesValidator.class)
#Documented
public #interface PasswordMatches {
String message() default "Passwords don't match";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Note, there is line
#Constraint(validatedBy = PasswordMatchesValidator.class).
In other words, the annotation class Constraint, like the other annotations in this class also, must have ANNOTATION_TYPE as a value of target annotation.
Now the password equality check is easy to include to data model class simply by adding annotation #PasswordMatches:
#PasswordMatches
public class UserDto {
...
}
The PasswordMatchesValidator class could look like this:
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, Object> {
#Override
public void initialize(final PasswordMatches constraintAnnotation) {}
#Override
public boolean isValid(final Object obj, final ConstraintValidatorContext context) {
final UserDto user = (UserDto) obj;
return user.getPassword().equals(user.getMatchingPassword());
}
}
Some already existing and well-known example of its usage would be great too.
There is quite well-known example in item 4, but another known annotations which are applied frequently to custom annotations are #Retention, #Documented and #Target itself.
For example, if annotation looks like
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface SomeAnnotation {
String description() default "This is example for class annotation";
}
the compiler will complain in this situation
#SomeAnnotation
public class SomeClass {
#SomeAnnotation // here it's complaning
public void someMethod(){}
}
If you change
#Target(ElementType.TYPE)
to
#Target({ElementType.METHOD, ElementType.TYPE})
it won't complain anymore.
Annotation are basically additional metadata (information) that goes along with your code. It can be placed along side types (Classes, Interfaces), methods, and arguments.
It is often useful during compile time and runtime. Many popular APIs such as Java EE 5+, Spring, AspectJ leverage annotation for code clarity and consistency.
Using annotation often allows code to be more readable, more easily understood.
I'd recommend you read through the annotation chapter on Java tutorial
In the past metadata are often given as an xml file, and it's difficult for someone trying to understand the code if they have to lookup a different xml configuration file. The latest Java servlet API allows mapping of servlet simply by using annotation -- as opposed of web.xml mapping:
#WebServlet("/response")
public class ResponseServlet extends HttpServlet {
// servlet code here...
}

Categories