|
3 | 3 | import java.lang.reflect.ParameterizedType; |
4 | 4 | import java.lang.reflect.Type; |
5 | 5 | import java.lang.reflect.TypeVariable; |
| 6 | +import java.util.ArrayDeque; |
6 | 7 | import java.util.Arrays; |
7 | | -import java.util.Stack; |
| 8 | +import java.util.Deque; |
8 | 9 |
|
9 | 10 | /** |
10 | 11 | * Cut down version of GenericTypeUtil from Helidon project Apache 2 license. |
11 | 12 | */ |
12 | 13 | final class GenericTypeUtil { |
13 | 14 |
|
14 | | -// private static final Type[] EMPTY_TYPE_ARRAY = {}; |
15 | | - |
16 | 15 | /** |
17 | 16 | * Return the Type for type parameter of {@code GenericType<T>}. |
18 | 17 | */ |
19 | 18 | static Type typeArgument(Class<?> clazz) { |
20 | 19 | // collect superclasses |
21 | | - Stack<Type> superclasses = new Stack<>(); |
| 20 | + Deque<Type> superclasses = new ArrayDeque<>(); |
22 | 21 | Type currentType; |
23 | 22 | Class<?> currentClass = clazz; |
24 | 23 | do { |
@@ -60,324 +59,4 @@ static Type typeArgument(Class<?> clazz) { |
60 | 59 | } |
61 | 60 | throw new IllegalArgumentException(currentType + " does not specify the type parameter T of GenericType<T>"); |
62 | 61 | } |
63 | | - |
64 | | -// /** |
65 | | -// * Returns an array type whose elements are all instances of {@code componentType}. |
66 | | -// */ |
67 | | -// static GenericArrayType arrayOf(Type elementType) { |
68 | | -// return new GenericArrayTypeImpl(elementType); |
69 | | -// } |
70 | | -// |
71 | | -// /** |
72 | | -// * Returns a new parameterized type, applying {@code typeArguments} to {@code rawType}. Use this |
73 | | -// * method if {@code rawType} is not enclosed in another type. |
74 | | -// */ |
75 | | -// static ParameterizedType newParameterizedType(Type rawType, Type... typeArguments) { |
76 | | -// if (typeArguments.length == 0) { |
77 | | -// throw new IllegalArgumentException("Missing type arguments for " + rawType); |
78 | | -// } |
79 | | -// return new ParameterizedTypeImpl(null, rawType, typeArguments); |
80 | | -// } |
81 | | -// |
82 | | -// static Type canonicalizeClass(Class<?> cls) { |
83 | | -// return cls.isArray() ? new GenericArrayTypeImpl(canonicalize(cls.getComponentType())) : cls; |
84 | | -// } |
85 | | -// |
86 | | -// /** |
87 | | -// * Returns a type that is functionally equal but not necessarily equal according to {@link |
88 | | -// * Object#equals(Object) Object.equals()}. |
89 | | -// */ |
90 | | -// static Type canonicalize(Type type) { |
91 | | -// if (type instanceof Class) { |
92 | | -// Class<?> c = (Class<?>) type; |
93 | | -// return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c; |
94 | | -// |
95 | | -// } else if (type instanceof ParameterizedType) { |
96 | | -// if (type instanceof ParameterizedTypeImpl) return type; |
97 | | -// ParameterizedType p = (ParameterizedType) type; |
98 | | -// return new ParameterizedTypeImpl( |
99 | | -// p.getOwnerType(), p.getRawType(), p.getActualTypeArguments()); |
100 | | -// |
101 | | -// } else if (type instanceof GenericArrayType) { |
102 | | -// if (type instanceof GenericArrayTypeImpl) return type; |
103 | | -// GenericArrayType g = (GenericArrayType) type; |
104 | | -// return new GenericArrayTypeImpl(g.getGenericComponentType()); |
105 | | -// |
106 | | -// } else if (type instanceof WildcardType) { |
107 | | -// if (type instanceof WildcardTypeImpl) return type; |
108 | | -// WildcardType w = (WildcardType) type; |
109 | | -// return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds()); |
110 | | -// |
111 | | -// } else { |
112 | | -// return type; // This type is unsupported! |
113 | | -// } |
114 | | -// } |
115 | | -// |
116 | | -// static int hashCodeOrZero(Object o) { |
117 | | -// return o != null ? o.hashCode() : 0; |
118 | | -// } |
119 | | -// |
120 | | -// static String typeToString(Type type) { |
121 | | -// return type instanceof Class ? ((Class<?>) type).getName() : type.toString(); |
122 | | -// } |
123 | | -// |
124 | | -// static void checkNotPrimitive(Type type) { |
125 | | -// if ((type instanceof Class<?>) && ((Class<?>) type).isPrimitive()) { |
126 | | -// throw new IllegalArgumentException("Unexpected primitive " + type + ". Use the boxed type."); |
127 | | -// } |
128 | | -// } |
129 | | -// |
130 | | -// static final class ParameterizedTypeImpl implements ParameterizedType { |
131 | | -// private final Type ownerType; |
132 | | -// private final Type rawType; |
133 | | -// public final Type[] typeArguments; |
134 | | -// |
135 | | -// ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) { |
136 | | -// // Require an owner type if the raw type needs it. |
137 | | -// if (ownerType != null && rawType instanceof Class<?>) { |
138 | | -// Class<?> enclosingClass = ((Class<?>) rawType).getEnclosingClass(); |
139 | | -// if (enclosingClass == null || Types.rawType(ownerType) != enclosingClass) { |
140 | | -// throw new IllegalArgumentException( |
141 | | -// "unexpected owner type for " + rawType + ": " + ownerType); |
142 | | -// |
143 | | -// } else if (enclosingClass != null) { |
144 | | -// throw new IllegalArgumentException("unexpected owner type for " + rawType + ": null"); |
145 | | -// } |
146 | | -// } |
147 | | -// |
148 | | -// this.ownerType = ownerType == null ? null : canonicalize(ownerType); |
149 | | -// this.rawType = canonicalize(rawType); |
150 | | -// this.typeArguments = typeArguments.clone(); |
151 | | -// for (int t = 0; t < this.typeArguments.length; t++) { |
152 | | -// if (this.typeArguments[t] == null) throw new NullPointerException(); |
153 | | -// checkNotPrimitive(this.typeArguments[t]); |
154 | | -// this.typeArguments[t] = canonicalize(this.typeArguments[t]); |
155 | | -// } |
156 | | -// } |
157 | | -// |
158 | | -// @Override |
159 | | -// public Type[] getActualTypeArguments() { |
160 | | -// return typeArguments.clone(); |
161 | | -// } |
162 | | -// |
163 | | -// @Override |
164 | | -// public Type getRawType() { |
165 | | -// return rawType; |
166 | | -// } |
167 | | -// |
168 | | -// @Override |
169 | | -// public Type getOwnerType() { |
170 | | -// return ownerType; |
171 | | -// } |
172 | | -// |
173 | | -// @Override |
174 | | -// public boolean equals(Object other) { |
175 | | -// return other instanceof ParameterizedType |
176 | | -// && GenericTypeUtil.equals(this, (ParameterizedType) other); |
177 | | -// } |
178 | | -// |
179 | | -// @Override |
180 | | -// public int hashCode() { |
181 | | -// return Arrays.hashCode(typeArguments) ^ rawType.hashCode() ^ hashCodeOrZero(ownerType); |
182 | | -// } |
183 | | -// |
184 | | -// @Override |
185 | | -// public String toString() { |
186 | | -// StringBuilder result = new StringBuilder(30 * (typeArguments.length + 1)); |
187 | | -// result.append(typeToString(rawType)); |
188 | | -// |
189 | | -// if (typeArguments.length == 0) { |
190 | | -// return result.toString(); |
191 | | -// } |
192 | | -// |
193 | | -// result.append("<").append(typeToString(typeArguments[0])); |
194 | | -// for (int i = 1; i < typeArguments.length; i++) { |
195 | | -// result.append(", ").append(typeToString(typeArguments[i])); |
196 | | -// } |
197 | | -// return result.append(">").toString(); |
198 | | -// } |
199 | | -// } |
200 | | -// |
201 | | -// static final class GenericArrayTypeImpl implements GenericArrayType { |
202 | | -// private final Type componentType; |
203 | | -// |
204 | | -// GenericArrayTypeImpl(Type componentType) { |
205 | | -// this.componentType = canonicalize(componentType); |
206 | | -// } |
207 | | -// |
208 | | -// @Override |
209 | | -// public Type getGenericComponentType() { |
210 | | -// return componentType; |
211 | | -// } |
212 | | -// |
213 | | -// @Override |
214 | | -// public boolean equals(Object o) { |
215 | | -// return o instanceof GenericArrayType && GenericTypeUtil.equals(this, (GenericArrayType) o); |
216 | | -// } |
217 | | -// |
218 | | -// @Override |
219 | | -// public int hashCode() { |
220 | | -// return componentType.hashCode(); |
221 | | -// } |
222 | | -// |
223 | | -// @Override |
224 | | -// public String toString() { |
225 | | -// return typeToString(componentType) + "[]"; |
226 | | -// } |
227 | | -// } |
228 | | -// |
229 | | -// /** |
230 | | -// * The WildcardType interface supports multiple upper bounds and multiple lower bounds. We only |
231 | | -// * support what the Java 6 language needs - at most one bound. If a lower bound is set, the upper |
232 | | -// * bound must be Object.class. |
233 | | -// */ |
234 | | -// static final class WildcardTypeImpl implements WildcardType { |
235 | | -// private final Type upperBound; |
236 | | -// private final Type lowerBound; |
237 | | -// |
238 | | -// WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) { |
239 | | -// if ((lowerBounds.length > 1) || (upperBounds.length != 1)) |
240 | | -// throw new IllegalArgumentException(); |
241 | | -// |
242 | | -// if (lowerBounds.length == 1) { |
243 | | -// if (lowerBounds[0] == null) throw new NullPointerException(); |
244 | | -// checkNotPrimitive(lowerBounds[0]); |
245 | | -// if (upperBounds[0] != Object.class) throw new IllegalArgumentException(); |
246 | | -// this.lowerBound = canonicalize(lowerBounds[0]); |
247 | | -// this.upperBound = Object.class; |
248 | | -// |
249 | | -// } else { |
250 | | -// if (upperBounds[0] == null) throw new NullPointerException(); |
251 | | -// checkNotPrimitive(upperBounds[0]); |
252 | | -// this.lowerBound = null; |
253 | | -// this.upperBound = canonicalize(upperBounds[0]); |
254 | | -// } |
255 | | -// } |
256 | | -// |
257 | | -// @Override |
258 | | -// public Type[] getUpperBounds() { |
259 | | -// return new Type[]{upperBound}; |
260 | | -// } |
261 | | -// |
262 | | -// @Override |
263 | | -// public Type[] getLowerBounds() { |
264 | | -// return lowerBound != null ? new Type[]{lowerBound} : EMPTY_TYPE_ARRAY; |
265 | | -// } |
266 | | -// |
267 | | -// @Override |
268 | | -// public boolean equals(Object other) { |
269 | | -// return other instanceof WildcardType && GenericTypeUtil.equals(this, (WildcardType) other); |
270 | | -// } |
271 | | -// |
272 | | -// @Override |
273 | | -// public int hashCode() { |
274 | | -// // This equals Arrays.hashCode(getLowerBounds()) ^ Arrays.hashCode(getUpperBounds()). |
275 | | -// return (lowerBound != null ? 31 + lowerBound.hashCode() : 1) ^ (31 + upperBound.hashCode()); |
276 | | -// } |
277 | | -// |
278 | | -// @Override |
279 | | -// public String toString() { |
280 | | -// if (lowerBound != null) { |
281 | | -// return "? super " + typeToString(lowerBound); |
282 | | -// } else if (upperBound == Object.class) { |
283 | | -// return "?"; |
284 | | -// } else { |
285 | | -// return "? extends " + typeToString(upperBound); |
286 | | -// } |
287 | | -// } |
288 | | -// } |
289 | | -// |
290 | | -// static String typeAnnotatedWithAnnotations(Type type, Set<? extends Annotation> annotations) { |
291 | | -// return type + (annotations.isEmpty() ? " (with no annotations)" : " annotated " + annotations); |
292 | | -// } |
293 | | -// |
294 | | -// /** |
295 | | -// * Returns a type that represents an unknown type that extends {@code bound}. For example, if |
296 | | -// * {@code bound} is {@code CharSequence.class}, this returns {@code ? extends CharSequence}. If |
297 | | -// * {@code bound} is {@code Object.class}, this returns {@code ?}, which is shorthand for {@code ? |
298 | | -// * extends Object}. |
299 | | -// */ |
300 | | -// static WildcardType subtypeOf(Type bound) { |
301 | | -// Type[] upperBounds; |
302 | | -// if (bound instanceof WildcardType) { |
303 | | -// upperBounds = ((WildcardType) bound).getUpperBounds(); |
304 | | -// } else { |
305 | | -// upperBounds = new Type[]{bound}; |
306 | | -// } |
307 | | -// return new WildcardTypeImpl(upperBounds, EMPTY_TYPE_ARRAY); |
308 | | -// } |
309 | | -// |
310 | | -// /** |
311 | | -// * Returns a type that represents an unknown supertype of {@code bound}. For example, if {@code |
312 | | -// * bound} is {@code String.class}, this returns {@code ? super String}. |
313 | | -// */ |
314 | | -// static WildcardType supertypeOf(Type bound) { |
315 | | -// Type[] lowerBounds; |
316 | | -// if (bound instanceof WildcardType) { |
317 | | -// lowerBounds = ((WildcardType) bound).getLowerBounds(); |
318 | | -// } else { |
319 | | -// lowerBounds = new Type[]{bound}; |
320 | | -// } |
321 | | -// return new WildcardTypeImpl(new Type[]{Object.class}, lowerBounds); |
322 | | -// } |
323 | | -// |
324 | | -// /** |
325 | | -// * Returns true if {@code a} and {@code b} are equal. |
326 | | -// */ |
327 | | -// static boolean equals(Type a, Type b) { |
328 | | -// if (a == b) { |
329 | | -// return true; // Also handles (a == null && b == null). |
330 | | -// |
331 | | -// } else if (a instanceof Class) { |
332 | | -// if (b instanceof GenericArrayType) { |
333 | | -// return equals( |
334 | | -// ((Class<?>) a).getComponentType(), ((GenericArrayType) b).getGenericComponentType()); |
335 | | -// } |
336 | | -// return a.equals(b); // Class already specifies equals(). |
337 | | -// |
338 | | -// } else if (a instanceof ParameterizedType) { |
339 | | -// if (!(b instanceof ParameterizedType)) return false; |
340 | | -// ParameterizedType pa = (ParameterizedType) a; |
341 | | -// ParameterizedType pb = (ParameterizedType) b; |
342 | | -// Type[] aTypeArguments = |
343 | | -// pa instanceof ParameterizedTypeImpl |
344 | | -// ? ((ParameterizedTypeImpl) pa).typeArguments |
345 | | -// : pa.getActualTypeArguments(); |
346 | | -// Type[] bTypeArguments = |
347 | | -// pb instanceof ParameterizedTypeImpl |
348 | | -// ? ((ParameterizedTypeImpl) pb).typeArguments |
349 | | -// : pb.getActualTypeArguments(); |
350 | | -// return equals(pa.getOwnerType(), pb.getOwnerType()) |
351 | | -// && pa.getRawType().equals(pb.getRawType()) |
352 | | -// && Arrays.equals(aTypeArguments, bTypeArguments); |
353 | | -// |
354 | | -// } else if (a instanceof GenericArrayType) { |
355 | | -// if (b instanceof Class) { |
356 | | -// return equals( |
357 | | -// ((Class<?>) b).getComponentType(), ((GenericArrayType) a).getGenericComponentType()); |
358 | | -// } |
359 | | -// if (!(b instanceof GenericArrayType)) return false; |
360 | | -// GenericArrayType ga = (GenericArrayType) a; |
361 | | -// GenericArrayType gb = (GenericArrayType) b; |
362 | | -// return equals(ga.getGenericComponentType(), gb.getGenericComponentType()); |
363 | | -// |
364 | | -// } else if (a instanceof WildcardType) { |
365 | | -// if (!(b instanceof WildcardType)) return false; |
366 | | -// WildcardType wa = (WildcardType) a; |
367 | | -// WildcardType wb = (WildcardType) b; |
368 | | -// return Arrays.equals(wa.getUpperBounds(), wb.getUpperBounds()) |
369 | | -// && Arrays.equals(wa.getLowerBounds(), wb.getLowerBounds()); |
370 | | -// |
371 | | -// } else if (a instanceof TypeVariable) { |
372 | | -// if (!(b instanceof TypeVariable)) return false; |
373 | | -// TypeVariable<?> va = (TypeVariable<?>) a; |
374 | | -// TypeVariable<?> vb = (TypeVariable<?>) b; |
375 | | -// return va.getGenericDeclaration() == vb.getGenericDeclaration() |
376 | | -// && va.getName().equals(vb.getName()); |
377 | | -// |
378 | | -// } else { |
379 | | -// // This isn't a supported type. |
380 | | -// return false; |
381 | | -// } |
382 | | -// } |
383 | 62 | } |
0 commit comments