The method-object, which the dynamic proxy receives, seems to be of the reference type instead of the object type, but only when generics are involved in the method signature. Should it work that way?
Example:
public class ProxyTest implements InvocationHandler {
public static interface A<T> {
void test(T t);
}
public static interface B extends A<String> {
@C
@Override
void test(String e);
}
@Retention(RetentionPolicy.RUNTIME)
public static @interface C {}
public static void main(String[] args) {
Class<A> a = A.class;
Class<? extends A<String>> bAsA = B.class;
Class<B> b = B.class;
A aProxy = ((A) Proxy.newProxyInstance(a.getClassLoader(), new Class[] {a}, new ProxyTest()));
A bAsAProxy = ((A) Proxy.newProxyInstance(bAsA.getClassLoader(), new Class[] {bAsA}, new ProxyTest()));
B bProxy = ((B) Proxy.newProxyInstance(b.getClassLoader(), new Class[] {b}, new ProxyTest()));
A bProxyAssignedToA = bProxy;
aProxy.test("");
bAsAProxy.test("");
bProxy.test("");
bProxyAssignedToA.test("");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
System.out.println(method.getDeclaringClass().getSimpleName() + ": " + (method.getAnnotation(C.class) != null ? "C" : "null"));
return null;
}
}
I expect it to print:
A: null
B: C
B: C
B: C
but the actual output is
A: null
B: null
B: C
B: null
When I change the generic of B to Object, or remove it, it correctly prints:
A: null
B: C
B: C
B: C