File A.java:
public interface A {
@Property(propertyName = "empoloyee.name")
String getEmployeeName();
@Property(propertyName = "employee.age")
String getEmployeeAge();
}
File B.java:
public class B {
public static void main(String[] args) {
for (Method method: A.class.getMethods()) {
Property property = method.getAnnotation(Property.class);
System.out.println("Property Name: " property.propertyName());
System.out.println("Property Value: " method.invoke());
}
}
}
Property.class:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Property {
String propertyName() default "";
String defaultValue() default "";
}
As shown in the above code snippet, my requirement is to invoke all the methods declared in A.class, in a loop.
Since these methods are annotated, just invoking them will return the property value. method.invoke() is giving me error. How do I resolve this issue?
CodePudding user response:
method.invoke needs object to pass for invoking the method so you will have pass an object of any class implementing interface A, like below -
public class C implements A{
@Override
public String getEmployeeName() {
return "xyz";
}
@Override
public String getEmployeeAge() {
return "22";
}
}
Then your main method will be like this -
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
C c = new C();
for (Method method: A.class.getMethods()) {
Property property = method.getAnnotation(Property.class);
System.out.println("Property Name: " property.propertyName());
System.out.println("Property Value: " method.invoke(c));
}
}
CodePudding user response:
I did some modifications to your code and I am hoping it helps. first of all, A is not a class it is just an interface and has methods with nobody, so in my case, I made an Employee class that implements the A interface:
public class Employee implements A {
private String employeeName;
private String employeeAge;
public Employee(String name, String age) {
this.employeeName = name;
this.employeeAge = age;
}
public String getEmployeeName() {
// TODO Auto-generated method stub
return employeeName;
}
public String getEmployeeAge() {
// TODO Auto-generated method stub
return employeeAge;
}
}
then inside Class B I called the Employee class
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class B {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
for (Method method: A.class.getMethods()) {
Employee em = new Employee("Roy", "20");
System.out.println("Property Name: " em.getEmployeeName());
System.out.println("Property Value: " method.invoke(em));
}
}
}
Property Annotation:
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// this annotation target only methods
@Target(ElementType.METHOD)
public @interface Property {
String propertyName() default "hi";
}
A interface:
// A is interface not a class
public interface A {
@Property(propertyName = "employee.name")
// this method is abstract: has no body
String getEmployeeName();
@Property(propertyName ="employee.age" )
// for good practice this should be integer instead of string
String getEmployeeAge();
}
I hope this answer your question. thanks