I have a class which has some properties and they are annotated with one custom annotation, and I want its information in another class.
How to create retrieve the annotation instance and how to get its extra info?
My source code:
/**custom annotation **/
public #interface Info {
public String name();
}
/**class where i used custom annotation **/
class ABC {
#Info(name="Institution Name")
private String Name;
}
You need to make your annotation with retention policy RetentionPolicy.RUNTIME in order to be able to acceed to your annotation on RUNTIME.
#Retention(RetentionPolicy.RUNTIME)
public #interface Info {
public String name();
}
After that you have to use this.getClass().getDeclaredField("name") in order to get your field.You can get your annotation with getAnnotation(Info.class) method. You will get an instance of your annotation and you will be able to acceed to its information.
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredField-java.lang.String-
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getAnnotation-java.lang.Class-
Related
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.
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;
}
My query is this. Say, i have a custom annotation as follows:
//rest of the code left out for the sake of brevity
interface #Name{
String myName();
}
Now, in the class where am using this annotation on say, a field or a method, i want to pass a value to "myName" from a property file, something like this:
#Name(myName="${read.my.name}")
public void something(){}
Could anyone please suggest how can i read the value passed to 'myName' in my annotation-processor from the property file? I have read a bit about the use of placeholders and then using #Value but am not sure i can/should use this approach in say, a service class where i just want to have an annotated field or method marked with this annotation? Any guidance would be much appreciated.
Thanks and regards!
Here's my method-level annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Name {
public String myName();
}
Here's a dummy class that declares the annotation:
public class Z {
#Name(myName = "George")
public void something() {
}
}
Here's how to get the value:
final Method method = Z.class.getMethod("something");
if (method.isAnnotationPresent(Name.class)) {
final Annotation annotation = method.getAnnotation(Name.class);
final Name name = (Name) annotation;
System.out.println(name.myName()); // Prints George
}
I am new with an annotated interface:
#interface
Test {
public String getInfo() default "hi";
}
#test
class TestImpl implements Test
{
public String getInfo(){return getInfo();}
public static void main(String...args)
{
TestImpl impl=new TestImpl ();
impl.getInfo();
}
}
Actually, I am totally confused with this, I want to print the default value of my getInfo() methods. and don't know how to use it and also the advantages of the annotated interface.
if some buddy has an idea about it, plz make changes of my above code as the printable format of default values, and also if it id possible then give me the URL from where I can read more about the annotated interface.
Thanks,
Subodh Ray
class TestImpl { // not implementing the annotation interface
and then:
Test annotation = TestImpl.class.getAnnotation(Test.class);
String info = annotation.getInfo();
Note that usually annotation attributes are not defined as getters. So info() instead of getInfo()
Update: you need #Retention(RetentionPolicy.RUNTIME) on your annotation class. If it is not there, the annotation is not preserved at runtime.
I need to create a custom constraint annotation which can access the value of another field of my bean. I'll use this annotation to validate the field because it depends on the value of the other but the way I define it the compiler says "The value for annotation attribute" of my field "must be a constant expression".
I've defined it in this way:
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy=EqualsFieldValidator.class)
#Documented
public #interface EqualsField {
public String field();
String message() default "{com.myCom.annotations.EqualsField.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class EqualsFieldValidator implements ConstraintValidator<EqualsField, String>{
private EqualsField equalsField;
#Override
public void initialize(EqualsField equalsField) {
this.equalsField = equalsField;
}
#Override
public boolean isValid(String thisField, ConstraintValidatorContext arg1) {
//my validation
}
}
and in my bean I want something like this:
public class MyBean{
private String field1;
#EqualsField(field=field1)
private String field2;
}
Is there any way to define the annotation so the field value can be a variable?
Thanks
The easiest thing to do is take one step back: the constraint/validator you have written works on a field-level, but what you want to enforce is a cross-field dependency i.e. a class-level constraint.
Rewrite your constraint and validator to work at the class level (i.e. the annotation will go on the class, not on the field). That way you'll get access to the entire class. In your isValid(..) method, simply do a get on both the fields, compare, and return appropriately.
As the compiler said annotations must be constant (i.e. you can determine the value at compile time.) Now If I'm guessing correctly it looks like you are using this annotation to denote that the values of those fields should be equal when run through the equals field validator. One approach you could take is using reflection. Instead of trying to annotate with the value, annotate with the field name instead
public class MyBean{
private String field1;
#EqualsField("field1")
private String field2;
}
Then in your validator you can read the name of the field and use reflection to access it
Object o = object.getClass().getDeclaredField(annotationValue).get(object);
o == object.(field with annotation) OR
o.equals(object.(field with annotation));
Depending on what you are trying to do you may need to add in logic based on the field type, but still the same general principle.
Check out this previous question, has multiple solutions for cross-field validation: Cross field validation with Hibernate Validator (JSR 303)