10

更新- 質問をより明確にするために。

リフレクションを介してメソッドを呼び出しているときに ClassCastException を取得する原因として考えられるものは何ですか?

リフレクションを介してメソッドを呼び出そうとしているときに、アプリケーションの一部として次のスタック トレースを取得しました。

java.lang.IllegalArgumentException: java.lang.ClassCastException@21fea1fv
    at sun.reflect.GeneratedMethodAccessor332.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com..... 
    (remaining is my method stack trace)

サンプルクラスを試して、さまざまなタイプのさまざまな引数をそれに渡しましたが、常にこの例外が発生します。

java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)

更新- 例外を再作成するために書いたサンプルコードは次のとおりです

プロキシ クラスを作成するためのインターフェイス

package my.tests;

public interface ReflectionsInterface { 
    public abstract void doSomething();
}

これはテストクラスです

package my.tests;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Reflections implements ReflectionsInterface {

    public static void main(String[] args) {
        Reflections reflections = new Reflections();
        ReflectionsInterface reflectionsProxy = reflections.createProxy(ReflectionsInterface.class);
        invokeMethod(reflectionsProxy, "doSomething", null);
    }

    public <T> T createProxy(Class<T> entityInterface) {
        EntityInvocationHandler eih = new EntityInvocationHandler(this);
        T cast = entityInterface.cast(Proxy.newProxyInstance(
                entityInterface.getClassLoader(), new Class[]{entityInterface}, eih));
        return cast;
    }

    public static void invokeMethod(Object obj, String methodName, Object... args) {
        Method[] methods = obj.getClass().getMethods();
        try {
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    method.invoke(obj, args);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doSomething() {
        System.out.println("woo");
    }

    private final static class EntityInvocationHandler implements InvocationHandler,
            ReflectionsInterface {

        private Reflections reflectionObj;

        public EntityInvocationHandler(Reflections reflectionObj) {
            super();
            this.reflectionObj = reflectionObj;
        }

        @Override
        public void doSomething() {
            reflectionObj.doSomething();
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object invoke = method.invoke(this, args);
            return invoke;
        }

    }
}

いつ引数の型が一致せず、ClassCastExceptionが発生するのか理解できません。 例外を再作成することはできません。例外が発生する理由を知りたいです。それを再作成した作業コード、またはこの場合にこの例外をスローするソースコード参照は良いでしょう

Method.class の javadoc とソース コードを確認しましたが、このエラーが発生する理由がわかりません。

4

3 に答える 3

1

さて、これが問題です:

reflections.invokeMethod("doInt", 1L);

を呼び出しdoIntていますが、値を渡していlongます。Longしたがって、リフレクションは aをにキャストしようとしてIntegerいますが、これは無効です。

私はあなたが意味したと思います:

reflections.invokeMethod("doLong", 1L);
于 2013-04-16T16:49:15.040 に答える
0

このエラーを再現するには、コードを少し変更してください。

java.lang.IllegalArgumentException: argument type mismatch

ここにインターフェースがあります

public interface ReflectionsInterface
{
  public abstract void doSomething1(Integer i);
  public abstract void doSomething2(String s);
}

コンパイルするために、クラス Reflections と EntityInvocationHandler にメソッドを追加します。次に、このメソッドを main() に追加します。実行すると、エラーランタイムが生成されます。

invokeMethod(reflectionsProxy, "doSomething1", "1");

ClassCastException を取得しようとしましたが、成功しませんでした。より多くのオブジェクトがあり、無効な型がメソッドに渡されるため、おそらく元のコードで発生します。ログを追加し、ClassCastException を分離するためにデバッグを試みます。

于 2013-04-20T10:56:12.030 に答える