Retrieve Java Annotation Attribute
- Obtain
Method
instance. - Obtain annotation.
- Obtain annotation attribute value.
Something like:
Method m = getClass().getMethod("myMethod");
MyAnnotation a = m.getAnnotation(MyAnnotation.class);
MyValueType value1 = a.attribute1();
You'll need to catch / handle the appropriate exceptions, of course. The above assumes you are indeed retrieving method from the current class (replace getClass()
with Class.forName()
otherwise) and the method in question is public (use getDeclaredMethods()
if that's not the case)
How to get annotation class name, attribute values using reflection
Contrary to what one might expect, the elements of an annotation are not attributes - they are actually methods that return the provided value or a default value.
You have to iterate through the annotations' methods and invoke them to get the values. Use annotationType()
to get the annotation's class, the object returned by getClass()
is just a proxy.
Here is an example which prints all elements and their values of the @Resource
annotation of a class:
@Resource(name = "foo", description = "bar")
public class Test {
public static void main(String[] args) throws Exception {
for (Annotation annotation : Test.class.getAnnotations()) {
Class<? extends Annotation> type = annotation.annotationType();
System.out.println("Values of " + type.getName());
for (Method method : type.getDeclaredMethods()) {
Object value = method.invoke(annotation, (Object[])null);
System.out.println(" " + method.getName() + ": " + value);
}
}
}
}
Output:
Values of javax.annotation.Resource
name: foo
type: class java.lang.Object
lookup:
description: bar
authenticationType: CONTAINER
mappedName:
shareable: true
Thanks to Aaron for pointing out the you need to cast the null
argument to avoid warnings.
easy way to get annotation value of object member in Java
You cannot get the annotations of a field given it's value.
When you are calling your "Util" method, all you are passing it is the value of the field. It won't have enough information to access the annotation.
Here is a way you might do it...
public class SomeClass {
@Digits(fraction = 2, integer = 16)
private BigDecimal amount;
private void setAmount(double d) {
amount = BigDecimal.valueOf(d);
amount.setScale(Util.getFraction(this, "amount"));
}
public static void main(String[] args) {
new SomeClass().setAmount(12.3);
}
}
Notice I'm passing the instance of the object that the field is in and the name of the field to my "Util" method.
It can now get the actual value like this...
public class Util {
public static int getFraction(Object obj, String fieldName) {
try {
Digits annotation = obj.getClass().getDeclaredField(fieldName).getAnnotation(Digits.class);
return annotation.fraction();
} catch (NoSuchFieldException | SecurityException e) {
// BOOM!
throw new IllegalStateException("Something went awfully wrong...", e);
}
}
}
Get the Javax Validation Annotation Attribute Value
Since the annotation has a runtime retention, you can access it through reflection. For instance (ignoring any exceptions):
Field field = MyClass.class.getDeclaredField("data");
Size size = field.getAnnotation(Field.class);
int max = size.max();
If you want to get the value that triggered a constraint error, catch the ConstraintViolationException
. You can then get the constraint annotation from the violation. Another example:
// just some code to get a descriptor
ConstraintDescriptor<?> descriptor = constraintViolationException.getAnnotations().stream()
.map(ConstraintViolation::getConstraintDescriptor)
.findAny()
.orElseThrow();
// now its properties can be accessed
Map<String, Object> attributes = descriptor.getAttributes();
// attributes contains an entry with key "max" and value 10 for your @Size annotation
Size size = (Size) descriptor.getAnnotation();
int max = size.max();
How do I get the method in the annotation parameter in an Aspect and get the result of the method execution
I'm the questioner
I have solved this using Java reflection,as follows:
@Aspect
@Component
public class PreVisitAspect {
@Autowired
private PageVisit pv;
@Around("@annotation(preVisit)")
public Object around(ProceedingJoinPoint joinPoint, PreVisit preVisit) throws Throwable {
String value = preVisit.value();
//String value="@pas.hasAccess('xxxxxx')";
if(value.startsWith("@")){
String beanName=value.substring(value.indexOf("@")+1,value.indexOf("."));
String methodName=value.substring(value.indexOf(".")+1,value.indexOf("("));
String paramsStr=value.substring(value.indexOf("(")+2,value.lastIndexOf(")")-1);
Object[] paramsArr=paramsStr.split("','");
logger.info("beanName:"+beanName);
logger.info("methodName:"+methodName);
logger.info("paramsStr:"+paramsStr);
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Method method = ReflectionUtils.findMethod(appContext.getBean(beanName).getClass(), methodName,new Class[]{String.class} );
Boolean result = (Boolean)ReflectionUtils.invokeMethod(method, appContext.getBean(beanName),paramsArr);
logger.info(result.toString());
}
.....other Code.....
}
}
tks @Karthikeyan Vaithilingam
Retrieve annotation by name
Use asSubclass
. Unlike compiler generated type casts, which can only work with types known at compile-time, this will perform a check against the Class
object retrieved at runtime. Since this is safe, it won’t generated an “Unchecked cast” warning. Note the existence of a similar operation, cast
for casting an instance of a Class
. These methods were added in Java 5, specifically to aid code using Generics.
String annotationName = "java.lang.Deprecated";
Class<? extends Annotation> c = Class.forName(annotationName).asSubclass(Annotation.class);
boolean depr = Thread.class.getMethod("stop").isAnnotationPresent(c);
System.out.println(depr);
Get value of a parameter of an annotation in Java
To get value of the @Path
parameter:
String path = Hello.class.getAnnotation(Path.class).value();
Similarly, Once you have hold of Method
getHtml
Method m = Hello.class.getMethod("getHtml", ..);
String mime = m.getAnnotation(Produces.class).value;
Access to class attributes' values using Java Annotations
You need to iterate through the fields, get their annotations and set the value wherever the annotation matches (it can match multiple fields):
@Retention(RetentionPolicy.RUNTIME)
public @interface Field1 {}
@Retention(RetentionPolicy.RUNTIME)
public @interface Field2 {}
public static class UnderTest {
@Field1
private String field1;
@Field2
private int field2;
public UnderTest(String field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}
@Override
public String toString() {
return field1 + "=" + field2;
}
}
public static void setter(Object obj, Class<? extends Annotation> fieldAnnotation, Object fieldValue) throws IllegalAccessException {
for (Field field: obj.getClass().getDeclaredFields()) {
for (Annotation annot: field.getDeclaredAnnotations()) {
if (annot.annotationType().isAssignableFrom(fieldAnnotation)) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(obj, fieldValue);
}
}
}
}
public static void main(String[] argv) throws IllegalAccessException {
UnderTest underTest = new UnderTest("A", 1);
System.out.println(underTest);
setter(underTest, Field1.class, "B");
setter(underTest, Field2.class, 2);
System.out.println(underTest);
}
Running this prints
A=1
B=2
Related Topics
How to Call Methods in Constructor in Java
How to Create Variables at Runtime in Java
Compiler Error: "Class, Interface, or Enum Expected"
How to Get a Random Line of a Text File in Java
Java Serialization - Java.Io.Invalidclassexception Local Class Incompatible
How to Create a New Packaging Type for Maven
Java Implementation of JSON to Xml Conversion
Java "" Operator for Checking Null - What Is It? (Not Ternary!)
Superclass Reference Not Able to Call Subclass Method in Java
How to "Pretty Print" a Duration in Java
Apache Poi Error Loading Xssfworkbook Class
Get Integer Value of the Current Year in Java
Java 8 Streams - Collect VS Reduce
Getting Value of Public Static Final Field/Property of a Class in Java via Reflection
Messagebodyprovidernotfoundexception While Running Jar from Command Line