6

だから、私は奇妙な問題を抱えています。この式: method.invoke(target, null)java.lang.IllegalArgumentException をスローします: 引数の数が間違っています

問題は、この式が hibernate (正確には BasicPropertyAccessor$BasicGetter) の奥深くにあることであり、正常に動作するはずです (最近まで動作していました)。

私はこの問題をEclipseでデバッグしましたが、実際に(表示ビューで)呼び出すmethod.invoke(target)か、method.invoke(target, (Object[]) null)すべてが正常に機能する場合。私のクラスにはこのゲッターがあり、引数がないと確信しています。それで...問題は、一体何が起こっているのかということです!

編集:

  • method は java.lang.reflect.Method のインスタンスであり、前述のゲッターを指します
  • ターゲットは public X getX() getter を持つクラスのインスタンスです
  • JDK1.6.0_31
  • 休止状態のコード (BasicPropertyAccessor:143):

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

2 に答える 2

8

varargs メソッドに値を渡すと、null次の 2 つのいずれかとして解釈される可能性があります。

  • null配列_
  • である 1 つの要素を持つ配列null

nullが明示的に varargs メソッドのコンポーネント型にキャストされない限り、Java は前者を選択します。(わかりやすくするために、どちらの方法でも明示的にキャストすることをお勧めします。そうしないと、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また、新しいバージョンの hibernate では、それを明示的に にキャストしていることにも気付きましたObject[]

于 2012-08-12T02:23:58.547 に答える
0

メソッドのシグニチャーが の場合、パラメーターpublic X getX()存在しないため、次のように呼び出します。

method.invoke(target);

メソッドの最初のパラメーターは、invoke()メソッドを呼び出すインスタンスです。

varargs メソッドの場合、コンマでパラメーターを指定する方法は、たとえばのmethod(a, b, c)構文糖衣であることに注意してください。method(new Object[]{a, b, c}正式なパラメーターの型はObject[]です。

于 2012-08-12T02:24:07.593 に答える