private static final class Types.TypeVariableInvocationHandler
extends java.lang.Object
implements java.lang.reflect.InvocationHandler
Java 8 introduced a new method getAnnotatedBounds()
in the TypeVariable
interface, whose return type AnnotatedType[]
is also new in Java 8. That means that we
cannot implement that interface in source code in a way that will compile on both Java 7 and
Java 8. If we include the getAnnotatedBounds()
method then its return type means it
won't compile on Java 7, while if we don't include the method then the compiler will complain
that an abstract method is unimplemented. So instead we use a dynamic proxy to get an
implementation. If the method being called on the TypeVariable
instance has the same
name as one of the public methods of Types.TypeVariableImpl
, the proxy calls the same method
on its instance of TypeVariableImpl
. Otherwise it throws UnsupportedOperationException
; this should only apply to getAnnotatedBounds()
. This
does mean that users on Java 8 who obtain an instance of TypeVariable
from TypeResolver.resolveType(java.lang.reflect.Type)
will not be able to call getAnnotatedBounds()
on it, but that
should hopefully be rare.
TODO(b/147144588): We are currently also missing the methods inherited from AnnotatedElement
, which TypeVariable
began to extend only in Java 8. Those methods
refer only to types present in Java 7, so we could implement them in TypeVariableImpl
today. (We could probably then make TypeVariableImpl
implement AnnotatedElement
so that we get partial compile-time checking.)
This workaround should be removed at a distant future time when we no longer support Java versions earlier than 8.
Modifier and Type | Field and Description |
---|---|
private Types.TypeVariableImpl<?> |
typeVariableImpl |
private static ImmutableMap<java.lang.String,java.lang.reflect.Method> |
typeVariableMethods |
Constructor and Description |
---|
TypeVariableInvocationHandler(Types.TypeVariableImpl<?> typeVariableImpl) |
Modifier and Type | Method and Description |
---|---|
java.lang.Object |
invoke(java.lang.Object proxy,
java.lang.reflect.Method method,
java.lang.Object[] args) |
private static final ImmutableMap<java.lang.String,java.lang.reflect.Method> typeVariableMethods
private final Types.TypeVariableImpl<?> typeVariableImpl
TypeVariableInvocationHandler(Types.TypeVariableImpl<?> typeVariableImpl)