6

所以,我有一个奇怪的问题。这个表达式:method.invoke(target, null)throws java.lang.IllegalArgumentException: wrong number of arguments

问题是这个表达式在 hibernate 的深处(准确地说是 BasicPropertyAccessor$BasicGetter),我想它应该可以正常工作(直到最近才这样做)

我在 Eclipse 中调试了这个问题,实际上,如果我(在显示视图中)调用method.invoke(target)method.invoke(target, (Object[]) null)一切正常。我确定我的班级有这个吸气剂,它没有参数。所以……问题是,到底发生了什么?!

编辑:

  • method 是 java.lang.reflect.Method 的一个实例,并指向上述 getter
  • target 是具有公共 X getX() getter 的类的实例
  • JDK 1.6.0_31
  • 休眠代码(BasicPropertyAccessor:143):

    public Object get(Object target) throws HibernateException {
        try {
            return method.invoke(target, null);
        }
        catch{ ... }
    }
    
4

2 回答 2

8

当您将null值传递给 varargs 方法时,它可以被解释为以下两种情况之一:

  • 一个null数组
  • 具有一个元素的数组,即null.

Java 选择前者,除非null显式转换为 varargs 方法的组件类型。(为了清楚起见,建议您显式转换任何一种方式,如果不这样做,您还会在 Eclipse 中收到令人讨厌的警告。)

当调用不带参数的方法时,您可以传递Method.invoke一个包含 0 个元素、没有额外参数(这将导致一个空数组)的数组,或者一个null数组:

public class MethodInvoke {
    public static void noParams() {
        System.out.println("noParams called");
    }

    public static void main(String[] args) throws NoSuchMethodException,
            SecurityException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        Method noParams = MethodInvoke.class.getMethod("noParams");
        Object target = null;
        noParams.invoke(target, new Object[0]);
        noParams.invoke(target);
        noParams.invoke(target, null);
        noParams.invoke(target, (Object[]) null);
        noParams.invoke(target, (Object) null); // wrong number of arguments
    }
}

似乎正在发生的事情method.invoke(target, null)被解释为method.invoke(target, (Object) null). 这与 Java 的行为方式不一致。

你确定你的方法没有参数吗?

我还注意到,在较新版本的休眠中,他们明确地将其null转换为Object[].

于 2012-08-12T02:23:58.547 回答
0

如果方法的签名是public X getX(),那么没有参数,所以这样调用它:

method.invoke(target);

该方法的第一个参数invoke()是调用该方法的实例。

请注意,对于可变参数方法,使用逗号指定参数的方式例如method(a, b, c)是语法糖method(new Object[]{a, b, c}:形式参数类型是Object[].

于 2012-08-12T02:24:07.593 回答