Reputation: 3657
Hi I am creating a custom Excel parsing marshaller tool, you can reference this: How can I call getter/setter for property marked with custom annotation?
What I need now is to be able to find all annotations, specifically how can I find ones that nested objects or inner classes, and then call that setter/getter.
For example:
public class MyOuterClass {
private InnerClass innerObject;
public void setInnerObject (InnerClass innerObject) {
this.innerObject = innerObject;
}
public InnerClass getInnerObject() {
return innerObject;
}
}
and;
public class InnerClass {
// I need to get this field and call its setter from the class passed in, so something like:
// MyOuterClass outClass; outClass.getInnerObject.setFieldIWant("field")
// OR outClass.getInnerObject.getFieldIWant
// But have to be able to do at run time, having no knowledge of the class inside
// This must also work for a nested class
@ExcelColumn
private String fieldIWant;
public void setFieldIWant(String fieldIWant) {
this.fieldIWant = fieldIWant;
}
public String getFieldIWant() {
return fieldIWant;
}
}
Upvotes: 3
Views: 6795
Reputation: 3186
The following classes implement the AnnotatedElement
interface:
AccessibleObject
Class
Constructor
Field
Method
Package
On object instances of said classes you can then call the:
<object>.isAnnotationPresent(Class<? extends Annotation> annotationClass)
method in which you specify the annotation you wish to check for.
So in your case the method call for @ExcelColumn
would look like:
<object>.isAnnotationPresent(ExcelColumn.class)
Then you can just use reflection to iterate over the fields/methods etc. of the object you wish to check and call .isAnnotationPresent
method on each of them to check whether they have the said annotation or not.
So if you want to do some magic on fields (and nested fields) you could create a method like so:
public void doMagicToFields(Object someObject){
// Get all declared fields.
Field[] fields = someObject.getClass().getDeclaredFields();
for(Field field: fields){
// If the field is annotated by @ExcelColumn
if(field.isAnnotationPresent(ExcelColumn.class){
// If the field is a String (add more checks as needed)
if(String.class.equals(field.getType()){
// Set the fields value to "myValue" in case of String.
field.set(someObject, "myValue");
}
// Recursive call to check the nested fields of this field object.
doMagicToFields(
// We actually get the field object here.
field.get(someObject)
);
}
}
}
Upvotes: 6
Reputation: 36
To find inner classes MyOuterClass.class.getClasses()
will get you started, but will only give you one level of visibility. You'll need to iterate through those inner classes (e.g., SomeInnerClass.class.getClasses()
) to check if they have an inner class themselves.
Once you have your list of classes it's as simple as SomeClass.class.getMethods()
to get a list of all methods.
for(Class<?> clazz : OuterClass.class.getClasses()) {
for(Method method : clazz.getMethods()) {
if(method.getAnnotation(ExcelColumn.class) != null) {
System.out.println(clazz.getName() + "." + method.getName());
}
}
}
Upvotes: 1