Methods Summary |
---|
public static boolean | containsTypeVariable(java.lang.reflect.Type type)Check if the {@code type} contains a {@link TypeVariable} recursively.
Intuitively, a type variable is a type in a type expression that refers to a generic
type which is not known at the definition of the expression (commonly seen when
type parameters are used, e.g. {@code class Foo}).
See
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4
for a more formal definition of a type variable .
if (type == null) {
// Trivially false
return false;
} else if (type instanceof TypeVariable<?>) {
/*
* T -> trivially true
*/
return true;
} else if (type instanceof Class<?>) {
/*
* class Foo -> no type variable
* class Foo<T> - has a type variable
*
* This also covers the case of class Foo<T> extends ... / implements ...
* since everything on the right hand side would either include a type variable T
* or have no type variables.
*/
Class<?> klass = (Class<?>)type;
// Empty array => class is not generic
if (klass.getTypeParameters().length != 0) {
return true;
} else {
// Does the outer class(es) contain any type variables?
/*
* class Outer<T> {
* class Inner {
* T field;
* }
* }
*
* In this case 'Inner' has no type parameters itself, but it still has a type
* variable as part of the type definition.
*/
return containsTypeVariable(klass.getDeclaringClass());
}
} else if (type instanceof ParameterizedType) {
/*
* This is the "Foo<T1, T2, T3, ... Tn>" in the scope of a
*
* // no type variables here, T1-Tn are known at this definition
* class X extends Foo<T1, T2, T3, ... Tn>
*
* // T1 is a type variable, T2-Tn are known at this definition
* class X<T1> extends Foo<T1, T2, T3, ... Tn>
*/
ParameterizedType p = (ParameterizedType) type;
// This needs to be recursively checked
for (Type arg : p.getActualTypeArguments()) {
if (containsTypeVariable(arg)) {
return true;
}
}
return false;
} else if (type instanceof WildcardType) {
WildcardType wild = (WildcardType) type;
/*
* This is is the "?" inside of a
*
* Foo<?> --> unbounded; trivially no type variables
* Foo<? super T> --> lower bound; does T have a type variable?
* Foo<? extends T> --> upper bound; does T have a type variable?
*/
/*
* According to JLS 4.5.1
* (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.5.1):
*
* - More than 1 lower/upper bound is illegal
* - Both a lower and upper bound is illegal
*
* However, we use this 'array OR array' approach for readability
*/
return containsTypeVariable(wild.getLowerBounds()) ||
containsTypeVariable(wild.getUpperBounds());
}
return false;
|
private static boolean | containsTypeVariable(java.lang.reflect.Type[] typeArray)Check if any of the elements in this array contained a type variable.
Empty and null arrays trivially have no type variables.
if (typeArray == null) {
return false;
}
for (Type type : typeArray) {
if (containsTypeVariable(type)) {
return true;
}
}
return false;
|
public static android.hardware.camera2.utils.TypeReference | createSpecializedTypeReference(java.lang.Class klass)Create a specialized type reference from a dynamic class instance,
bypassing the standard compile-time checks.
As with a regular type reference, the {@code klass} must not contain
any type variables.
return new SpecializedTypeReference<T>(klass);
|
public static android.hardware.camera2.utils.TypeReference | createSpecializedTypeReference(java.lang.reflect.Type type)Create a specialized type reference from a dynamic {@link Type} instance,
bypassing the standard compile-time checks.
As with a regular type reference, the {@code type} must not contain
any type variables.
return new SpecializedBaseTypeReference(type);
|
public boolean | equals(java.lang.Object o)Compare two objects for equality.
A TypeReference is only equal to another TypeReference if their captured type {@code T}
is also equal.
// Note that this comparison could inaccurately return true when comparing types
// with nested type variables; therefore we ban type variables in the constructor.
return o instanceof TypeReference<?> && mType.equals(((TypeReference<?>)o).mType);
|
private static final java.lang.Class | getArrayClass(java.lang.Class componentType)
return Array.newInstance(componentType, 0).getClass();
|
public android.hardware.camera2.utils.TypeReference | getComponentType()Get the component type, e.g. {@code T} from {@code T[]}.
Type componentType = getComponentType(mType);
return (componentType != null) ?
createSpecializedTypeReference(componentType) :
null;
|
private static java.lang.reflect.Type | getComponentType(java.lang.reflect.Type type)
checkNotNull(type, "type must not be null");
if (type instanceof Class<?>) {
return ((Class<?>) type).getComponentType();
} else if (type instanceof ParameterizedType) {
return null;
} else if (type instanceof GenericArrayType) {
return ((GenericArrayType)type).getGenericComponentType();
} else if (type instanceof WildcardType) {
// Should be at most 1 upper bound, but treat it like an array for simplicity
throw new UnsupportedOperationException("TODO: support wild card components");
} else if (type instanceof TypeVariable) {
throw new AssertionError("Type variables are not allowed in type references");
} else {
// Impossible
throw new AssertionError("Unhandled branch to get component type for type " + type);
}
|
public final java.lang.Class | getRawType()Returns the raw type of T.
- If T is a Class itself, T itself is returned.
- If T is a ParameterizedType, the raw type of the parameterized type is returned.
- If T is a GenericArrayType, the returned type is the corresponding array class.
For example: {@code List[]} => {@code List[]}.
- If T is a type variable or a wildcard type, the raw type of the first upper bound is
returned. For example: {@code } => {@code Foo}.
return (Class<? super T>)getRawType(mType);
|
private static final java.lang.Class | getRawType(java.lang.reflect.Type type)
if (type == null) {
throw new NullPointerException("type must not be null");
}
if (type instanceof Class<?>) {
return (Class<?>)type;
} else if (type instanceof ParameterizedType) {
return (Class<?>)(((ParameterizedType)type).getRawType());
} else if (type instanceof GenericArrayType) {
return getArrayClass(getRawType(((GenericArrayType)type).getGenericComponentType()));
} else if (type instanceof WildcardType) {
// Should be at most 1 upper bound, but treat it like an array for simplicity
return getRawType(((WildcardType) type).getUpperBounds());
} else if (type instanceof TypeVariable) {
throw new AssertionError("Type variables are not allowed in type references");
} else {
// Impossible
throw new AssertionError("Unhandled branch to get raw type for type " + type);
}
|
private static final java.lang.Class | getRawType(java.lang.reflect.Type[] types)
if (types == null) {
return null;
}
for (Type type : types) {
Class<?> klass = getRawType(type);
if (klass != null) {
return klass;
}
}
return null;
|
public java.lang.reflect.Type | getType()Return the dynamic {@link Type} corresponding to the captured type {@code T}.
return mType;
|
public int | hashCode(){@inheritDoc}
return mHash;
|
public java.lang.String | toString(){@inheritDoc}
StringBuilder builder = new StringBuilder();
builder.append("TypeReference<");
toString(getType(), builder);
builder.append(">");
return builder.toString();
|
private static void | toString(java.lang.reflect.Type type, java.lang.StringBuilder out)
if (type == null) {
return;
} else if (type instanceof TypeVariable<?>) {
// T
out.append(((TypeVariable<?>)type).getName());
} else if (type instanceof Class<?>) {
Class<?> klass = (Class<?>)type;
out.append(klass.getName());
toString(klass.getTypeParameters(), out);
} else if (type instanceof ParameterizedType) {
// "Foo<T1, T2, T3, ... Tn>"
ParameterizedType p = (ParameterizedType) type;
out.append(((Class<?>)p.getRawType()).getName());
toString(p.getActualTypeArguments(), out);
} else if (type instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType)type;
toString(gat.getGenericComponentType(), out);
out.append("[]");
} else { // WildcardType, BoundedType
// TODO:
out.append(type.toString());
}
|
private static void | toString(java.lang.reflect.Type[] types, java.lang.StringBuilder out)
if (types == null) {
return;
} else if (types.length == 0) {
return;
}
out.append("<");
for (int i = 0; i < types.length; ++i) {
toString(types[i], out);
if (i != types.length - 1) {
out.append(", ");
}
}
out.append(">");
|