3

java.lang.reflect.Proxy.newInstance(...)そのオブジェクトのへの呼び出しを使用してインターフェイスのインスタンスを作成するfinalizeと、invocationHandlerに渡されません。この動作が文書化されている場所を誰かに教えてもらえますか?

private Method lastInvokedMethod = null;

@Test
public void finalize_methods_seem_to_disappear_on_proxies() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    final Method lengthMethod = CharSequence.class.getDeclaredMethod("length");
    final Method finalizeMethod = Object.class.getDeclaredMethod("finalize");
    final Method equalsMethod = Object.class.getDeclaredMethod("equals", new Class[] {Object.class});

    InvocationHandler handler = new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            lastInvokedMethod = method;
            if (method.equals(lengthMethod))
                return 42;
            else if (method.equals(equalsMethod))
                return true;
            else
                return null;
        }
    };
    CharSequence proxy = (CharSequence) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[]{CharSequence.class}, handler);

    // check that invocationHandler is working via reflection
    lastInvokedMethod = null;
    assertEquals(42, invokeMethod(proxy, lengthMethod));
    assertEquals(lengthMethod, lastInvokedMethod);

    // check that other methods defined on Object are delegated
    lastInvokedMethod = null;
    assertEquals(true, invokeMethod(proxy, equalsMethod, "banana"));
    assertEquals(equalsMethod, lastInvokedMethod);

    // check that we can invoke finalize through reflection
    Object finalizableObject = new Object() {
        protected void finalize() throws Throwable {
            lastInvokedMethod = finalizeMethod;
            super.finalize();
        }
    };
    lastInvokedMethod = null;
    invokeMethod(finalizableObject, finalizeMethod);
    assertEquals(finalizeMethod, lastInvokedMethod);

    // Finally - a call to finalize is not delegated
    lastInvokedMethod = null;
    invokeMethod(proxy, finalizeMethod);
    assertNull(lastInvokedMethod);
}

private Object invokeMethod(Object object, Method method, Object... args) throws IllegalAccessException, InvocationTargetException {
    method.setAccessible(true);
    return method.invoke(object, args);
}
4

1 に答える 1

8

java.lang.reflect.Proxy API

•プロキシインスタンスのjava.lang.Objectで宣言されたhashCode、equals、またはtoStringメソッドの呼び出しは、上記のように、インターフェイスメソッドの呼び出しがエンコードされてディスパッチされるのと同じ方法で、エンコードされ、呼び出しハンドラのinvokeメソッドにディスパッチされます。 。呼び出すために渡されるMethodオブジェクトの宣言クラスはjava.lang.Objectになります。java.lang.Objectから継承されたプロキシインスタンスの他のパブリックメソッドはプロキシクラスによってオーバーライドされないため、これらのメソッドの呼び出しは、java.lang.Objectのインスタンスの場合と同じように動作します

于 2013-01-06T16:45:20.077 に答える