2013-01-06 28 views
3

當我使用java.lang.reflect.Proxy.newInstance(...)創建一個接口實例時,該對象上的finalize調用沒有被傳遞給invocationHandler。任何人都可以指出我的行爲記錄在哪裏?java.lang.reflect.Proxy實例是否專門用於最終化處理?

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); 
} 

回答

8

java.lang.reflect.Proxy API

•哈希碼的調用,等於或代理實例在java.lang.Object中聲明的toString方法將被編碼並以相同的方式指派到調用處理程序的invoke方法因爲接口方法調用被編碼和調度,如上所述。傳遞給invoke的Method對象的聲明類將是java.lang.Object。 從java.lang.Object繼承的代理實例的其他公有方法不會被代理類重寫,因此這些方法的調用與對java.lang.Object實例的調用類似。

+1

謝謝 - 在我得到那麼多之前,我的眼睛明顯已經開始流血了! –