使用思考:如何测试方法

时间:2012-08-03 16:10:03

标签: java testing reflection

我最近在java中看过Reflections,我想出了一个简单的例子

Reflection.java

 import java.lang.reflect.*;

  public class Reflection{
  }

  public static void main(String args[])
  {
     try {
       Class cls = Class.forName("Method");

        Method methlist[] 
          = cls.getDeclaredMethods();
        for (int i = 0; i < methlist.length;
           i++) {  
           Method m = methlist[i];
           System.out.println("name 
             = " + m.getName());
           System.out.println("decl class = " +
                          m.getDeclaringClass());
           Class pvec[] = m.getParameterTypes();
           for (int j = 0; j < pvec.length; j++)
              System.out.println("
               param #" + j + " " + pvec[j]);
           Class evec[] = m.getExceptionTypes();
           for (int j = 0; j < evec.length; j++)
              System.out.println("exc #" + j 
                + " " + evec[j]);
           System.out.println("return type = " +
                              m.getReturnType());
           System.out.println("-----");
        }
     }
     catch (Throwable e) {
        System.err.println(e);
     }
  }
 }

Method.java

 public class Method {
  private int f1(
   Object p, int x) throws NullPointerException
  {
     if (p == null)
        throw new NullPointerException();
     return x;
  }

从上面的示例中,我可以返回Method.java的所有信息,如下所示

name = f1
decl class = class Method
param #0 class java.lang.Object
param #1 int
exc #0 class java.lang.NullPointerException
return type = int
-----
name = main
decl class = class method1
param #0 class [Ljava.lang.String;
return type = void
-----

但我的问题是,有没有办法从Method.java测试Reflection.java

int x = cls.getMethod("f1", Object = anObject, Integer.TYPE = 2 )
System.out.println(x);

控制台应该打印2,因为f1被传递了一个对象?

3 个答案:

答案 0 :(得分:1)

查看Javadoc for java.lang.reflect.Method。您需要方法invoke();

Method m = ...
Object result = m.invoke(objectToCallMethodOn, firstArgument, secondArgument);
int x = ((Integer) result).intValue();

答案 1 :(得分:1)

您需要使用这两个参数创建Method的实例,并使用调用私有方法f1。它将返回一个对象。您的代码中存在一些陷阱,但这是一个有效的解决方案(注意:我将您的班级Method重命名为MyMethod以避免名称冲突:

Method f1Method = MyMethod.class.getDeclaredMethod("f1", Object.class, int.class);
f1Method.setAccessible(true);
int result = (Integer) f1Method.invoke(new MyMethod(), 
                           new Object[]{new Object(), 2});
System.out.println(result);
  • 该方法是私有,因此您需要获取声明的方法并使其可访问
  • 该方法不是静态的,因此我们需要一个MyMethod实例来调用方法
  • 我们传递并接收java原始类型。允许int.class。 JavaDoc告诉我们,如果值具有基本类型,则首先将其适当地包装在对象中。因此,我们会收到Integer
  • 的实例

答案 2 :(得分:0)

注意:我引用的Method类是Method class in the JDK,而不是示例中的

您已经能够从Method对象中找到Class。您现在可以使用Method#invoke方法调用某个对象上的方法