(decl, name, bs, f);
}
/**
* Returns an array of Type objects representing the
* upper bound(s) of this type variable. Note that if no upper bound is
* explicitly declared, the upper bound is Object.
*
* For each upper bound B:
*
* - if B is a parameterized type or a type variable, it is created,
* (see {@link #ParameterizedType} for the details of the creation
* process for parameterized types).
*
- Otherwise, B is resolved.
*
*
* @throws TypeNotPresentException if any of the
* bounds refers to a non-existent type declaration
* @throws MalformedParameterizedTypeException if any of the
* bounds refer to a parameterized type that cannot be instantiated
* for any reason
* @return an array of Types representing the upper bound(s) of this
* type variable
*/
public Type[] getBounds() {
// lazily initialize bounds if necessary
if (bounds == null) {
FieldTypeSignature[] fts = getBoundASTs(); // get AST
// allocate result array; note that
// keeping ts and bounds separate helps with threads
Type[] ts = new Type[fts.length];
// iterate over bound trees, reifying each in turn
for ( int j = 0; j < fts.length; j++) {
Reifier r = getReifier();
fts[j].accept(r);
ts[j] = r.getResult();
}
// cache result
bounds = ts;
// could throw away bound ASTs here; thread safety?
}
return bounds.clone(); // return cached bounds
}
/**
* Returns the GenericDeclaration object representing the
* generic declaration that declared this type variable.
*
* @return the generic declaration that declared this type variable.
*
* @since 1.5
*/
public D getGenericDeclaration(){
if (genericDeclaration instanceof Class)
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
else if ((genericDeclaration instanceof Method) ||
(genericDeclaration instanceof Constructor))
ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration);
else
throw new AssertionError("Unexpected kind of GenericDeclaration");
return genericDeclaration;
}
/**
* Returns the name of this type variable, as it occurs in the source code.
*
* @return the name of this type variable, as it appears in the source code
*/
public String getName() { return name; }
public String toString() {return getName();}
@Override
public boolean equals(Object o) {
if (o instanceof TypeVariable &&
o.getClass() == TypeVariableImpl.class) {
TypeVariable> that = (TypeVariable>) o;
GenericDeclaration thatDecl = that.getGenericDeclaration();
String thatName = that.getName();
return Objects.equals(genericDeclaration, thatDecl) &&
Objects.equals(name, thatName);
} else
return false;
}
@Override
public int hashCode() {
return genericDeclaration.hashCode() ^ name.hashCode();
}
// Implementations of AnnotatedElement methods.
@SuppressWarnings("unchecked")
public T getAnnotation(Class annotationClass) {
Objects.requireNonNull(annotationClass);
// T is an Annotation type, the return value of get will be an annotation
return (T)mapAnnotations(getAnnotations()).get(annotationClass);
}
public T getDeclaredAnnotation(Class annotationClass) {
Objects.requireNonNull(annotationClass);
return getAnnotation(annotationClass);
}
@Override
public T[] getAnnotationsByType(Class annotationClass) {
Objects.requireNonNull(annotationClass);
return AnnotationSupport.getDirectlyAndIndirectlyPresent(mapAnnotations(getAnnotations()), annotationClass);
}
@Override
public T[] getDeclaredAnnotationsByType(Class annotationClass) {
Objects.requireNonNull(annotationClass);
return getAnnotationsByType(annotationClass);
}
public Annotation[] getAnnotations() {
int myIndex = typeVarIndex();
if (myIndex < 0)
throw new AssertionError("Index must be non-negative.");
return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex);
}
public Annotation[] getDeclaredAnnotations() {
return getAnnotations();
}
public AnnotatedType[] getAnnotatedBounds() {
return TypeAnnotationParser.parseAnnotatedBounds(getBounds(),
getGenericDeclaration(),
typeVarIndex());
}
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
// Helpers for annotation methods
private int typeVarIndex() {
TypeVariable>[] tVars = getGenericDeclaration().getTypeParameters();
int i = -1;
for (TypeVariable> v : tVars) {
i++;
if (equals(v))
return i;
}
return -1;
}
private static Map, Annotation> mapAnnotations(Annotation[] annos) {
Map, Annotation> result =
new LinkedHashMap<>();
for (Annotation a : annos) {
Class extends Annotation> klass = a.annotationType();
AnnotationType type = AnnotationType.getInstance(klass);
if (type.retention() == RetentionPolicy.RUNTIME)
if (result.put(klass, a) != null)
throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
}
return result;
}
}