1 package sun.reflect.generics.reflectiveObjects;
3 import sun.reflect.generics.tree.FieldTypeSignature;
5 import java.lang.reflect.MalformedParameterizedTypeException;
6 import java.lang.reflect.Method;
7 import java.lang.reflect.ParameterizedType;
8 import java.lang.reflect.Type;
9 import java.lang.reflect.TypeVariable;
10 import java.util.Arrays;
11 import java.util.Objects;
13 // TODO: Fix for Groovy's model-checking
15 * MJI model class for sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
17 * This is a JPF specific version of a system class because we can't use the real,
18 * platform VM specific version (it's native all over the place, its field
19 * structure isn't documented, most of its methods are private, hence we can't
20 * even instantiate it properly).
22 * Note that this class never gets seen by the real VM - it's for JPF's eyes only.
26 /** Implementing class for ParameterizedType interface. */
27 public class ParameterizedTypeImpl implements ParameterizedType {
28 private final Type[] actualTypeArguments;
29 private final Class<?> rawType;
30 private final Type ownerType;
32 private ParameterizedTypeImpl(Class<?> rawType,
33 Type[] actualTypeArguments,
35 this.actualTypeArguments = actualTypeArguments;
36 this.rawType = rawType;
37 this.ownerType = (ownerType != null) ? ownerType : rawType.getDeclaringClass();
38 validateConstructorArguments();
41 private void validateConstructorArguments() {
42 TypeVariable<?>[] formals = rawType.getTypeParameters();
43 // check correct arity of actual type args
44 if (formals.length != actualTypeArguments.length){
45 throw new MalformedParameterizedTypeException();
47 for (int i = 0; i < actualTypeArguments.length; i++) {
48 // check actuals against formals' bounds
53 * Static factory. Given a (generic) class, actual type arguments
54 * and an owner type, creates a parameterized type.
56 public static ParameterizedTypeImpl make(Class<?> rawType,
57 Type[] actualTypeArguments,
59 return new ParameterizedTypeImpl(rawType, actualTypeArguments,
63 public Type[] getActualTypeArguments() {
64 return actualTypeArguments.clone();
68 * Returns the <tt>Type</tt> object representing the class or interface
69 * that declared this type.
71 * @return the <tt>Type</tt> object representing the class or interface
72 * that declared this type
74 public Class<?> getRawType() {
79 public Type getOwnerType() {
84 public boolean equals(Object o) {
85 if (o instanceof ParameterizedType) {
86 // Check that information is equivalent
87 ParameterizedType that = (ParameterizedType) o;
92 Type thatOwner = that.getOwnerType();
93 Type thatRawType = that.getRawType();
95 if (false) { // Debugging
96 boolean ownerEquality = (ownerType == null ?
98 ownerType.equals(thatOwner));
99 boolean rawEquality = (rawType == null ?
100 thatRawType == null :
101 rawType.equals(thatRawType));
103 boolean typeArgEquality = Arrays.equals(actualTypeArguments, // avoid clone
104 that.getActualTypeArguments());
105 for (Type t : actualTypeArguments) {
106 System.out.printf("\t\t%s%s%n", t, t.getClass());
109 System.out.printf("\towner %s\traw %s\ttypeArg %s%n",
110 ownerEquality, rawEquality, typeArgEquality);
111 return ownerEquality && rawEquality && typeArgEquality;
115 Objects.equals(ownerType, thatOwner) &&
116 Objects.equals(rawType, thatRawType) &&
117 Arrays.equals(actualTypeArguments, // avoid clone
118 that.getActualTypeArguments());
124 public int hashCode() {
126 Arrays.hashCode(actualTypeArguments) ^
127 Objects.hashCode(ownerType) ^
128 Objects.hashCode(rawType);
131 public String toString() {
132 StringBuilder sb = new StringBuilder();
134 if (ownerType != null) {
135 if (ownerType instanceof Class)
136 sb.append(((Class)ownerType).getName());
138 sb.append(ownerType.toString());
142 if (ownerType instanceof ParameterizedTypeImpl) {
143 // Find simple name of nested type by removing the
144 // shared prefix with owner.
145 sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
148 sb.append(rawType.getName());
150 sb.append(rawType.getName());
152 if (actualTypeArguments != null &&
153 actualTypeArguments.length > 0) {
155 boolean first = true;
156 for(Type t: actualTypeArguments) {
159 sb.append(t.getTypeName());
165 return sb.toString();