java custom annotation: make an attribute optional - java

I defined my own custom annotation
#Target(value={ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
public #interface MyCustomAnnotation {
Class<?> myType();
}
how, if at all, can I make the attribute optional

You can provide a default value for the attribute:
#Target(value={ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
public #interface MyCustomAnnotation {
Class<?> myType() default Object.class;
}

Found it. It can't be optional, but a default can be declared like this:
#Target(value={ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
public #interface MyCustomAnnotation {
Class<?> myType() default String.class;
}
If no default can make sense as "empty" value then that is a problem.

For Optional attribute you need to provide default value for that attribute you can provide default value using "default" keyword.
Note : For only one attribute you can use attribute name as value.
If you use your attribute name as value you can directly pass value like this #MyCustomAnnotation(true) instead of #MyCustomAnnotation(myType = true).
See this example for more details

Related

Add an annotation to check if any of the class object fields is null java

I want to add an annotation which essentially verifies if any of the fields in the java class object is null. It should return true if any of the object values is null, otherwise false.. i.e
#NameBinding
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.CLASS)
public #interface IsNull {}
I should be able to use this annotation on any of the classes
Eg:
#IsNull
public class EmployeeRequest {
String name;
}
Usage:
EmployeeRequest empRequest = new EmployeeRequest();
if(empRequest.isNull())
fail request
Is this possible?
I want to add this as an annotation because , i want to use this isNull on different classes.

Using one annotation as a member of another annotation in Java

I am new to Java annotation. I have used the following annotation in my Spring boot application as follows:
Original annotation definition:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface MyAnnotation {
EntityType entityType();
ActionType actionType();
Resource resourceType();
}
Now I would like to move actionType() and resourceType() to a different annotation say MySubAnnotation and use it in the original above annotation MyAnnotation as follows:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface MyAnnotation {
EntityType entityType();
MySubAnnotation mySubAnnotation();
}
But I am facing an issue with using this as follows:
#MyAnnotation(entityType = EntityType.MY_ENTITY,
mySubAnnotation = <???>) <---HERE I CANNOT UNDERSTAND WHAT TO SPECIFY
#MySubAnnotation(actionType=ActionType.UPDATE,
resourceType=Resource.MY_RESOURCE)
public void myMethod() {
...
}
As mentioned above, I cannot understand what to specify for sub annotation. Could anyone please help here? Thanks.
You didn’t include the declaration of your MySubAnnotation. Besides that, the syntax for the actual annotation values is not different for nested annotations. You just have to place it after the =:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface MyAnnotation {
EntityType entityType();
MySubAnnotation mySubAnnotation();
}
#Retention(RetentionPolicy.RUNTIME)
#Target({})
public #interface MySubAnnotation {
ActionType actionType();
Resource resourceType();
}
#MyAnnotation(
entityType = EntityType.MY_ENTITY,
mySubAnnotation = #MySubAnnotation(
actionType = ActionType.UPDATE,
resourceType = Resource.MY_RESOURCE
)
)
public void myMethod() {
}
Note that in this example, MySubAnnotation has an empty list of targets, i.e. #Target({}) which permits it only as a value within other annotations. Of course, you could add other permitted targets. That would not affect its use as “sub annotation”, as that’s always allowed.
But there’s not much advantage in designing annotation parts as sub annotation here. All you’ve achieved, is requiring more typing. One imaginable possibility, is to provided a default here, e.g.
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface MyAnnotation {
EntityType entityType();
MySubAnnotation mySubAnnotation() default
#MySubAnnotation(actionType=ActionType.UPDATE, resourceType=Resource.MY_RESOURCE);
}
The difference to just specifying defaults for actionType and resourceType is that now, the developer may use the default for MySubAnnotation, i.e. both values, or has to specify explicit values for both, they can not override only one of them.

Java Annotation how to get current ElemenType of specific annotation

My annotation:
#Target({ElementType.TYPE, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
public #interface ObjectName {
String name() default "";
String field() default "";
}
Some class with my annotation
#ObjectName("a_")
public class A {
#ObjectName("field_")
String filed;
}
Problem - when i get all my "ObjectName" annotations from class above, how can i get annotation's ElementType value (field, class or method type)?
So i want something like this
public void process(Class<?> clazz) {
Annotation[] annotations = clazz.getAnnotations();
for (Annotation anno : annotations) {
if (anno instanceof ObjectName) {
ObjectName annObjName = (ObjectName) anno;
Target target = anno.getAnnotation(Target.class);
if (target.getType().equals(ElementType.TYPE)
doThat(annObjName.name());
else if (target.getType().equals(ElementType.FIELD)
doThis(annObjName.field());
}
}
}
Can i even do this?
How can i do this or how can i find out if this annotation declared on filed or class?
You can't.
All you can do is look at where you call getAnnotations(), because you seem to incorrectly believe that clazz.getAnnotations() will return all annotations on everything in the class. That is false. When you call clazz.getAnnotations(), you will only get the annotations directly on the class. To get annotations on fields, you must call clazz.getFields(), and then call getAnnotations() on the Field elements. So there's no risk of getting them mixed up as long as you keep those straight.

Define custom annotation within another custom annotation with default value

I am trying to declare custom annotation in following way:
Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.METHOD})
public #interface InnerAnnotation {
}
Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.METHOD})
public #interface OuterAnnotation {
public String default "";
public InnerAnnotation innerAnnotation(); //here I wanted to do "public InnerAnnotation innerAnnotation() default {some default value}"
}
I wanted to use it in a way:
class first{
#OuterAnnotation(value = "new") //wanted to declare something like this without need to define innerAnnotation
public void func(){
}
}
I wanted to assign some default value to inner annotation usage(so that I don't have to provide any mandatory value while using it), but some how I am not able to do that as compiler asks for compile time constant for this.Can any please suggest how to use inner annotation with any default value ?
The syntax for what you what is as follows:
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.METHOD})
public #interface OuterAnnotation {
public String default "";
public InnerAnnotation innerAnnotation() default #InnerAnnotation(); //this does the trick;
}

Java - get annotation is always null

I am new to annotations, i have classes annotated with custom annotation FXMLController, send these classes to a factory to get the value from the annotation, but it is always null ~
annotation :
public #interface FXMLController {
String value() default "";
}
usage :
#FXMLController(value=CommonConstants.SPLASH_SCREEN)
public class SplashScreenController{ ....... )
getting the value :
Annotation annotation = controller.getAnnotation(FXMLController.class);
FXMLController fxmlController = (FXMLController) annotation;
I guess that you forgot to mark your annotation as #Retention(RetentionPolicy.RUNTIME)
EDIT:
In fact your annotation should look like:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documentedpublic #interface FXMLController {
String value() default "";
}

Categories