I\'m following this tutorial on Java annotaitons and implemented the Test annotation as shown there. But when running the code I get the following output.
java.l
The Method#invoke has the answer to your question:
public Object invoke(Object obj,
Object... args)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
Throws:
NullPointerException
- if the specified object is null and the method is an instance method.
The problem is that you are passing a null target object to method.invoke(object)
method.
The target object should not be null, else a nullpointerexception is expected.
The invoke method has below usages:
Method.invoke(targetObject, args1, args2, args3...); where args1, args2, args3 etc are argument to the method being invoked.
This issue is here:
method.invoke(null);
This method's first parameter is the object to invoke the method on. This is the dynamic (reflection) equivalent of something like this:
Object foo = null;
foo.toString();
Of course we would expect this code to give a NullPointerException
because foo
is null
.
The parameter that you pass to invoke
must be an object on which the method is invoked, unless the method is static
. What you did through reflection is equivalent to this:
MyTest obj = null;
obj.testBlah();
Naturally, there's an NPE. To fix this problem, pass an object on which to invoke the method, or make the method static
.
Here is one way to make a fix:
public <T> void parse(Class<T> clazz, T obj) throws Exception {
Method[] methods = clazz.getMethods();
int pass = 0;
int fail = 0;
for (Method method : methods) {
if (method.isAnnotationPresent(Test.class)) {
Test test = method.getAnnotation(Test.class);
Class expected = test.expected();
try {
method.invoke(obj);
pass++;
} catch (Exception e) {
if (Exception.class != expected) {
e.printStackTrace();
fail++;
} else {
pass++;
}
}
}
}
System.out.println("Passed:" + pass + " Fail:" + fail);
}
...
parser.parse(MyTest.class, new MyTest());
Demo on ideone.