2013-09-14 5 views
5

Я следую за этим tutorial on Java annotaitons и внедрил тестовую аннотацию, как показано на ней. Но при запуске кода я получаю следующий вывод.Получение java.lang.NullPointerException при вызове метода Method.invoke

java.lang.NullPointerException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:616) 
    at TestAnnotationParser.parse(Demo.java:24) 
    at Demo.main(Demo.java:51) 
Passed:0 Fail:1 

Следующий мой код. Может ли кто-нибудь указать, что я ошибался?

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import java.lang.reflect.Method; 

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@interface Test { 
    Class expected(); 
} 

class TestAnnotationParser { 
    public void parse(Class<?> clazz) 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(null); 
        pass++; 
       } catch (Exception e) { 
        if (Exception.class != expected) { 
         e.printStackTrace(); 
         fail++; 
        } else { 
         pass++; 
        } 
       } 
      } 
     } 
     System.out.println("Passed:" + pass + " Fail:" + fail); 
    } 
} 

class MyTest { 

    @Test(expected = RuntimeException.class) 
    public void testBlah() { 
    } 
} 

public class Demo { 
    public static void main(String[] args) { 
     TestAnnotationParser parser = new TestAnnotationParser(); 
     try { 
      parser.parse(MyTest.class); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Какой номер строки 24 ?? – prasanth

+0

@prasanth Строка с 'method.invoke (null);' –

ответ

10

Параметр, передаваемый invoke должен быть объект, на котором вызывается метод, если метод не является static. То, что вы сделали с помощью отражения, равнозначно этому:

MyTest obj = null; 
obj.testBlah(); 

Естественно, есть NPE. Чтобы устранить эту проблему, передайте объект, для которого нужно вызвать метод, или сделайте метод static.

Вот один из способов сделать исправление:

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.

+0

Просто заметьте, вы можете получить аналогичную ошибку NullPointerException, если вы проигнорируете исключение NoSuchMethodException при попытке получить метод через отражение. – bbarker

1

Этот вопрос здесь:

method.invoke(null); 

первый параметр данного метода является объект для вызова метода на. Это динамическое (отражение) эквивалент чего-то вроде этого:

Object foo = null; 
foo.toString(); 

Конечно, мы ожидали бы этот код, чтобы дать NullPointerException потому что foo является null.

+0

В следующий раз попробуйте объяснить, что является правильным решением. –

1

Проблема в том, что вы передаете нулевой целевой объект методу method.invoke(object). Целевой объект не должен быть нулевым, иначе ожидается появление nullpointerexception.

Метод Invoke имеет ниже использований:

Method.invoke(targetObject, args1, args2, args3...); where args1, args2, args3 etc are argument to the method being invoked.

2

Method#invoke есть ответ на ваш вопрос:

public Object invoke(Object obj, 
      Object... args) 
       throws IllegalAccessException, 
        IllegalArgumentException, 
        InvocationTargetException 

Броски: NullPointerException - если указанный объект является недействительным и метод является методом экземпляра.

Смежные вопросы