Search code examples
javagenericscastingdynamic-proxy

Type casting silently failed with dynamic proxy and java generics


IMy question concerns the behavior of type casting with dynamic proxy and java generics. More specifically, I want to instrument a servelet object using dynamic proxy. For better reusability, I adopted some generic code template for creating proxy objects as below.

@SuppressWarnings("unchecked")
public static <T> T instrument(final T aT) {
    T proxy = (T) Proxy.newProxyInstance(aT.getClass().getClassLoader(), new Class[]{MyServelet.class}, new InvocationHandler() {
        @Override
        public Object invoke(Object aProxy, Method aMethod, Object[] aArgs) throws Throwable {
        ..... instrumentation logic goes here
        }
    });
     System.out.println("proxy class " + proxy.getClass());
     System.out.println("input class " + aT.getClass());
     return proxy;
}

Here T is my concrete servelet implementation class that implements MyServelet Interface. However, If I run the above method it prints out

proxy class class com.sun.proxy.$Proxy0
input class class MyServeletImplementation

So I wonder what happened to the type casting statement in the code snippet. It seems like it quietly failed since the proxy didn't get casted to MyServeletImplementation, but it didn't throw ClassCastException either. Can somebody shed me some light on this? Thanks!


Solution

  • No cast took place in the actual compiled bytecode of the method, because of type erasure.

    When generating bytecode, the compiler treats any variable of a parameter type as having the same type as that parameter type's upper bound, or Object if the type is unbounded. So if T in your method had the constraint <T extends MyServelet>, the compiler would have treated proxy as a variable of type MyServelet, and inserted a cast. However, as T is unbounded, it's treated as a variable of type Object - thus, no cast.