1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.reflect;
18
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.junit.jupiter.api.Assumptions.assumeTrue;
26
27 import java.awt.Insets;
28 import java.io.Serializable;
29 import java.lang.reflect.Constructor;
30 import java.lang.reflect.Field;
31 import java.lang.reflect.GenericArrayType;
32 import java.lang.reflect.Method;
33 import java.lang.reflect.ParameterizedType;
34 import java.lang.reflect.Type;
35 import java.lang.reflect.TypeVariable;
36 import java.lang.reflect.WildcardType;
37 import java.net.URI;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.Comparator;
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Properties;
47 import java.util.TreeSet;
48
49 import org.apache.commons.lang3.AbstractLangTest;
50 import org.apache.commons.lang3.JavaVersion;
51 import org.apache.commons.lang3.SystemUtils;
52 import org.apache.commons.lang3.reflect.testbed.Foo;
53 import org.apache.commons.lang3.reflect.testbed.GenericParent;
54 import org.apache.commons.lang3.reflect.testbed.GenericTypeHolder;
55 import org.apache.commons.lang3.reflect.testbed.StringParameterizedChild;
56 import org.junit.jupiter.api.Disabled;
57 import org.junit.jupiter.api.Test;
58
59 final class AAAClass extends AAClass<String> {
60 public class BBBClass extends BBClass<String> {
61
62 }
63 }
64
65 @SuppressWarnings("unused")
66 class AAClass<T> {
67
68 public class BBClass<S> {
69
70 }
71 }
72
73 @SuppressWarnings("rawtypes")
74
75 final class AClass extends AAClass<String>.BBClass<Number> {
76
77 @SuppressWarnings("unused")
78 public interface AInterface<T> {
79
80 }
81
82 @SuppressWarnings("unused")
83 public class BClass<T> {
84
85 }
86
87 @SuppressWarnings("unused")
88 public class CClass<T> extends BClass {
89
90 }
91
92 @SuppressWarnings("unused")
93 public class DClass<T> extends CClass<T> {
94
95 }
96
97 @SuppressWarnings("unused")
98 public class EClass<T> extends DClass {
99
100 }
101
102 public class FClass extends EClass<String> {
103
104 }
105
106 public class GClass<T extends BClass<? extends T> & AInterface<AInterface<? super T>>> {
107
108 }
109
110 public BClass<Number> bClass;
111
112 public CClass<? extends String> cClass;
113
114 public DClass<String> dClass;
115
116 public EClass<String> eClass;
117
118 public FClass fClass;
119
120 public GClass gClass;
121
122 AClass(final AAClass<String> enclosingInstance) {
123 enclosingInstance.super();
124 }
125 }
126 @SuppressWarnings("rawtypes")
127 abstract class Test1<G> {
128 public abstract Object m0();
129 public abstract String[] m1();
130 public abstract <K, V> Map<? extends K, V[]> m10();
131 public abstract <K, V> Map<? extends K, List<V[]>> m11();
132 public abstract List m12();
133 public abstract Map m13();
134 public abstract Properties m14();
135 public abstract G m15();
136 public abstract List<G> m16();
137 public abstract Enum m17();
138 public abstract <E> E[] m2();
139 public abstract <E> List<? extends E> m3();
140 public abstract <E extends Enum<E>> List<? extends Enum<E>> m4();
141 public abstract List<? extends Enum<?>> m5();
142 public abstract List<? super Enum<?>> m6();
143 public abstract List<?> m7();
144 public abstract Map<? extends Enum<?>, ? super Enum<?>> m8();
145 public abstract <K, V> Map<? extends K, ? super V[]> m9();
146 }
147
148
149
150
151 @SuppressWarnings({ "unchecked", "unused", "rawtypes" })
152
153 public class TypeUtilsTest<B> extends AbstractLangTest {
154
155 public interface And<K, V> extends This<Number, Number> {
156 }
157
158 public static class ClassWithSuperClassWithGenericType extends ArrayList<Object> {
159 private static final long serialVersionUID = 1L;
160
161 public static <U> Iterable<U> methodWithGenericReturnType() {
162 return null;
163 }
164 }
165
166 public class Other<T> implements This<String, T> {
167 }
168
169 public class Tester implements This<String, B> {
170 }
171
172 public class That<K, V> implements This<K, V> {
173 }
174
175 public class The<K, V> extends That<Number, Number> implements And<String, String> {
176 }
177
178 public class Thing<Q> extends Other<B> {
179 }
180
181 public interface This<K, V> {
182 }
183
184 public static Comparable<String> stringComparable;
185
186 public static Comparable<URI> uriComparable;
187
188 public static Comparable<Integer> intComparable;
189
190 public static Comparable<Long> longComparable;
191
192 public static Comparable<?> wildcardComparable;
193
194 public static URI uri;
195
196 public static List<String>[] stringListArray;
197
198 public static <G extends Comparable<G>> G stub() {
199 return null;
200 }
201
202 public static <G extends Comparable<? super G>> G stub2() {
203 return null;
204 }
205
206 public static <T extends Comparable<? extends T>> T stub3() {
207 return null;
208 }
209
210 public This<String, String> dis;
211
212 public That<String, String> dat;
213
214 public The<String, String> da;
215
216 public Other<String> uhder;
217
218 public Thing ding;
219
220 public TypeUtilsTest<String>.Tester tester;
221
222 public Tester tester2;
223
224 public TypeUtilsTest<String>.That<String, String> dat2;
225
226 public TypeUtilsTest<Number>.That<String, String> dat3;
227
228 public Comparable<? extends Integer>[] intWildcardComparable;
229
230 public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
231
232 public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) {
233 final Type type1 = types[i1];
234 final Type type2 = types[i2];
235 final boolean isAssignable = TypeUtils.isAssignable(type2, type1);
236
237 if (expected) {
238 assertTrue(isAssignable,
239 "[" + i1 + ", " + i2 + "]: From "
240 + String.valueOf(type2) + " to "
241 + String.valueOf(type1));
242 } else {
243 assertFalse(isAssignable,
244 "[" + i1 + ", " + i2 + "]: From "
245 + String.valueOf(type2) + " to "
246 + String.valueOf(type1));
247 }
248 }
249
250 public void dummyMethod(final List list0, final List<Object> list1, final List<?> list2,
251 final List<? super Object> list3, final List<String> list4, final List<? extends String> list5,
252 final List<? super String> list6, final List[] list7, final List<Object>[] list8, final List<?>[] list9,
253 final List<? super Object>[] list10, final List<String>[] list11, final List<? extends String>[] list12,
254 final List<? super String>[] list13) {
255 }
256
257 @Test
258 public void test_LANG_1114() throws Exception {
259 final Type nonWildcardType = getClass().getDeclaredField("wildcardComparable").getGenericType();
260 final Type wildcardType = ((ParameterizedType) nonWildcardType).getActualTypeArguments()[0];
261
262 assertFalse(TypeUtils.equals(wildcardType, nonWildcardType));
263 assertFalse(TypeUtils.equals(nonWildcardType, wildcardType));
264 }
265
266 @Test
267 public void test_LANG_1190() throws Exception {
268 final Type fromType = ClassWithSuperClassWithGenericType.class.getDeclaredMethod("methodWithGenericReturnType").getGenericReturnType();
269 final Type failingToType = TypeUtils.wildcardType().withLowerBounds(ClassWithSuperClassWithGenericType.class).build();
270
271 assertTrue(TypeUtils.isAssignable(fromType, failingToType));
272 }
273
274 @Test
275 public void test_LANG_1348() throws Exception {
276 final Method method = Enum.class.getMethod("valueOf", Class.class, String.class);
277 assertEquals("T extends java.lang.Enum<T>", TypeUtils.toString(method.getGenericReturnType()));
278 }
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299 @Test
300 public void test_LANG_1698() {
301
302 assumeTrue(SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_16));
303 final ParameterizedType comparing = (ParameterizedType) Arrays.stream(Comparator.class.getDeclaredMethods())
304 .filter(k -> k.getName().equals("comparing")).findFirst()
305 .orElse(Comparator.class.getDeclaredMethods()[0]).getGenericParameterTypes()[0];
306 final String typeName = TypeUtils
307 .parameterize((Class<?>) comparing.getRawType(), comparing.getActualTypeArguments()).getTypeName();
308 assertEquals("java.util.function.Function<? super T, ? extends U>", typeName);
309 }
310
311 @Test
312 public void test_LANG_820() {
313 final Type[] typeArray = {String.class, String.class};
314 final Type[] expectedArray = {String.class};
315 assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray));
316 }
317
318 @Test
319 public void testContainsTypeVariables() throws Exception {
320 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m0").getGenericReturnType()));
321 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m1").getGenericReturnType()));
322 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m2").getGenericReturnType()));
323 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m3").getGenericReturnType()));
324 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m4").getGenericReturnType()));
325 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m5").getGenericReturnType()));
326 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m6").getGenericReturnType()));
327 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m7").getGenericReturnType()));
328 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m8").getGenericReturnType()));
329 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m9").getGenericReturnType()));
330 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m10").getGenericReturnType()));
331 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m11").getGenericReturnType()));
332 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m12").getGenericReturnType()));
333 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m13").getGenericReturnType()));
334 assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m14").getGenericReturnType()));
335 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m15").getGenericReturnType()));
336 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m16").getGenericReturnType()));
337 assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m17").getGenericReturnType()));
338 }
339
340 @Test
341 public void testDetermineTypeVariableAssignments() throws SecurityException,
342 NoSuchFieldException {
343 final ParameterizedType iterableType = (ParameterizedType) getClass().getField("iterable")
344 .getGenericType();
345 final Map<TypeVariable<?>, Type> typeVarAssigns = TypeUtils.determineTypeArguments(TreeSet.class,
346 iterableType);
347 final TypeVariable<?> treeSetTypeVar = TreeSet.class.getTypeParameters()[0];
348 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar));
349 assertEquals(iterableType.getActualTypeArguments()[0], typeVarAssigns
350 .get(treeSetTypeVar));
351
352 assertThrows(NullPointerException.class,
353 () -> TypeUtils.determineTypeArguments(TreeSet.class, null));
354 assertThrows(NullPointerException.class,
355 () -> TypeUtils.determineTypeArguments(null, iterableType));
356 }
357
358 @Test
359 public void testGenericArrayType() throws Exception {
360 final Type expected = getClass().getField("intWildcardComparable").getGenericType();
361 final GenericArrayType actual =
362 TypeUtils.genericArrayType(TypeUtils.parameterize(Comparable.class, TypeUtils.wildcardType()
363 .withUpperBounds(Integer.class).build()));
364 assertTrue(TypeUtils.equals(expected, actual));
365 assertEquals("java.lang.Comparable<? extends java.lang.Integer>[]", actual.toString());
366 }
367
368 @Test
369 public void testGetArrayComponentType() throws Exception {
370 final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
371 List.class, List.class, List.class, List.class, List[].class, List[].class,
372 List[].class, List[].class, List[].class, List[].class, List[].class);
373
374 final Type[] types = method.getGenericParameterTypes();
375
376 assertNull(TypeUtils.getArrayComponentType(types[0]));
377 assertNull(TypeUtils.getArrayComponentType(types[1]));
378 assertNull(TypeUtils.getArrayComponentType(types[2]));
379 assertNull(TypeUtils.getArrayComponentType(types[3]));
380 assertNull(TypeUtils.getArrayComponentType(types[4]));
381 assertNull(TypeUtils.getArrayComponentType(types[5]));
382 assertNull(TypeUtils.getArrayComponentType(types[6]));
383 assertEquals(types[0], TypeUtils.getArrayComponentType(types[7]));
384 assertEquals(types[1], TypeUtils.getArrayComponentType(types[8]));
385 assertEquals(types[2], TypeUtils.getArrayComponentType(types[9]));
386 assertEquals(types[3], TypeUtils.getArrayComponentType(types[10]));
387 assertEquals(types[4], TypeUtils.getArrayComponentType(types[11]));
388 assertEquals(types[5], TypeUtils.getArrayComponentType(types[12]));
389 assertEquals(types[6], TypeUtils.getArrayComponentType(types[13]));
390 }
391
392 @Test
393 public void testGetPrimitiveArrayComponentType() {
394 assertEquals(boolean.class, TypeUtils.getArrayComponentType(boolean[].class));
395 assertEquals(byte.class, TypeUtils.getArrayComponentType(byte[].class));
396 assertEquals(short.class, TypeUtils.getArrayComponentType(short[].class));
397 assertEquals(int.class, TypeUtils.getArrayComponentType(int[].class));
398 assertEquals(char.class, TypeUtils.getArrayComponentType(char[].class));
399 assertEquals(long.class, TypeUtils.getArrayComponentType(long[].class));
400 assertEquals(float.class, TypeUtils.getArrayComponentType(float[].class));
401 assertEquals(double.class, TypeUtils.getArrayComponentType(double[].class));
402
403 assertNull(TypeUtils.getArrayComponentType(boolean.class));
404 assertNull(TypeUtils.getArrayComponentType(byte.class));
405 assertNull(TypeUtils.getArrayComponentType(short.class));
406 assertNull(TypeUtils.getArrayComponentType(int.class));
407 assertNull(TypeUtils.getArrayComponentType(char.class));
408 assertNull(TypeUtils.getArrayComponentType(long.class));
409 assertNull(TypeUtils.getArrayComponentType(float.class));
410 assertNull(TypeUtils.getArrayComponentType(double.class));
411 }
412
413 @Test
414 public void testGetRawType() throws SecurityException, NoSuchFieldException {
415 final Type stringParentFieldType = GenericTypeHolder.class.getDeclaredField("stringParent").getGenericType();
416 final Type integerParentFieldType = GenericTypeHolder.class.getDeclaredField("integerParent").getGenericType();
417 final Type foosFieldType = GenericTypeHolder.class.getDeclaredField("foos").getGenericType();
418 final Type genericParentT = GenericParent.class.getTypeParameters()[0];
419 assertEquals(GenericParent.class, TypeUtils.getRawType(stringParentFieldType, null));
420 assertEquals(GenericParent.class, TypeUtils.getRawType(integerParentFieldType, null));
421 assertEquals(List.class, TypeUtils.getRawType(foosFieldType, null));
422 assertEquals(String.class, TypeUtils.getRawType(genericParentT, StringParameterizedChild.class));
423 assertEquals(String.class, TypeUtils.getRawType(genericParentT, stringParentFieldType));
424 assertEquals(Foo.class, TypeUtils.getRawType(Iterable.class.getTypeParameters()[0], foosFieldType));
425 assertEquals(Foo.class, TypeUtils.getRawType(List.class.getTypeParameters()[0], foosFieldType));
426 assertNull(TypeUtils.getRawType(genericParentT, GenericParent.class));
427 assertEquals(GenericParent[].class, TypeUtils.getRawType(GenericTypeHolder.class.getDeclaredField("barParents").getGenericType(), null));
428 }
429
430
431
432
433 @Test
434 public void testGetRawType_LANG_1697() throws NoSuchFieldException {
435 assertEquals(int[].class, TypeUtils.getRawType(TypeUtils.genericArrayType(Integer.TYPE), Integer.TYPE));
436
437 assertNull(TypeUtils.getRawType(TypeUtils.genericArrayType(TypeUtils.WILDCARD_ALL), null));
438
439 assertNull(TypeUtils.getRawType(TypeUtils.genericArrayType(TypeUtils.WILDCARD_ALL), TypeUtils.WILDCARD_ALL));
440
441 assertNull(TypeUtils.getRawType(TypeUtils.genericArrayType(TypeUtils.WILDCARD_ALL), Integer.TYPE));
442 }
443
444 @Test
445 public void testGetTypeArguments() {
446 Map<TypeVariable<?>, Type> typeVarAssigns;
447 TypeVariable<?> treeSetTypeVar;
448 Type typeArg;
449
450 typeVarAssigns = TypeUtils.getTypeArguments(Integer.class, Comparable.class);
451 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
452 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
453 "Type var assigns for Comparable from Integer: " + typeVarAssigns);
454 typeArg = typeVarAssigns.get(treeSetTypeVar);
455 assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
456 "Type argument of Comparable from Integer: " + typeArg);
457
458 typeVarAssigns = TypeUtils.getTypeArguments(int.class, Comparable.class);
459 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
460 assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
461 "Type var assigns for Comparable from int: " + typeVarAssigns);
462 typeArg = typeVarAssigns.get(treeSetTypeVar);
463 assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
464 "Type argument of Comparable from int: " + typeArg);
465
466 final Collection<Integer> col = Collections.emptyList();
467 typeVarAssigns = TypeUtils.getTypeArguments(List.class, Collection.class);
468 treeSetTypeVar = Comparable.class.getTypeParameters()[0];
469 assertFalse(typeVarAssigns.containsKey(treeSetTypeVar),
470 "Type var assigns for Collection from List: " + typeVarAssigns);
471
472 typeVarAssigns = TypeUtils.getTypeArguments(AAAClass.BBBClass.class, AAClass.BBClass.class);
473 assertEquals(2, typeVarAssigns.size());
474 assertEquals(String.class, typeVarAssigns.get(AAClass.class.getTypeParameters()[0]));
475 assertEquals(String.class, typeVarAssigns.get(AAClass.BBClass.class.getTypeParameters()[0]));
476
477 typeVarAssigns = TypeUtils.getTypeArguments(Other.class, This.class);
478 assertEquals(2, typeVarAssigns.size());
479 assertEquals(String.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
480 assertEquals(Other.class.getTypeParameters()[0], typeVarAssigns.get(This.class.getTypeParameters()[1]));
481
482 typeVarAssigns = TypeUtils.getTypeArguments(And.class, This.class);
483 assertEquals(2, typeVarAssigns.size());
484 assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
485 assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[1]));
486
487 typeVarAssigns = TypeUtils.getTypeArguments(Thing.class, Other.class);
488 assertEquals(2, typeVarAssigns.size());
489 assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(getClass().getTypeParameters()[0]));
490 assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(Other.class.getTypeParameters()[0]));
491 }
492
493 @Test
494 public void testIsArrayGenericTypes() throws Exception {
495 final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
496 List.class, List.class, List.class, List.class, List[].class, List[].class,
497 List[].class, List[].class, List[].class, List[].class, List[].class);
498
499 final Type[] types = method.getGenericParameterTypes();
500
501 assertFalse(TypeUtils.isArrayType(types[0]));
502 assertFalse(TypeUtils.isArrayType(types[1]));
503 assertFalse(TypeUtils.isArrayType(types[2]));
504 assertFalse(TypeUtils.isArrayType(types[3]));
505 assertFalse(TypeUtils.isArrayType(types[4]));
506 assertFalse(TypeUtils.isArrayType(types[5]));
507 assertFalse(TypeUtils.isArrayType(types[6]));
508 assertTrue(TypeUtils.isArrayType(types[7]));
509 assertTrue(TypeUtils.isArrayType(types[8]));
510 assertTrue(TypeUtils.isArrayType(types[9]));
511 assertTrue(TypeUtils.isArrayType(types[10]));
512 assertTrue(TypeUtils.isArrayType(types[11]));
513 assertTrue(TypeUtils.isArrayType(types[12]));
514 assertTrue(TypeUtils.isArrayType(types[13]));
515 }
516
517 @Test
518 public void testIsArrayTypeClasses() {
519 assertTrue(TypeUtils.isArrayType(boolean[].class));
520 assertTrue(TypeUtils.isArrayType(byte[].class));
521 assertTrue(TypeUtils.isArrayType(short[].class));
522 assertTrue(TypeUtils.isArrayType(int[].class));
523 assertTrue(TypeUtils.isArrayType(char[].class));
524 assertTrue(TypeUtils.isArrayType(long[].class));
525 assertTrue(TypeUtils.isArrayType(float[].class));
526 assertTrue(TypeUtils.isArrayType(double[].class));
527 assertTrue(TypeUtils.isArrayType(Object[].class));
528 assertTrue(TypeUtils.isArrayType(String[].class));
529
530 assertFalse(TypeUtils.isArrayType(boolean.class));
531 assertFalse(TypeUtils.isArrayType(byte.class));
532 assertFalse(TypeUtils.isArrayType(short.class));
533 assertFalse(TypeUtils.isArrayType(int.class));
534 assertFalse(TypeUtils.isArrayType(char.class));
535 assertFalse(TypeUtils.isArrayType(long.class));
536 assertFalse(TypeUtils.isArrayType(float.class));
537 assertFalse(TypeUtils.isArrayType(double.class));
538 assertFalse(TypeUtils.isArrayType(Object.class));
539 assertFalse(TypeUtils.isArrayType(String.class));
540 }
541
542 @SuppressWarnings("boxing")
543 @Test
544 public void testIsAssignable() throws SecurityException, NoSuchMethodException,
545 NoSuchFieldException {
546 List list0 = null;
547 List<Object> list1;
548 List<?> list2;
549 List<? super Object> list3;
550 List<String> list4;
551 List<? extends String> list5;
552 List<? super String> list6;
553 List[] list7 = null;
554 List<Object>[] list8;
555 List<?>[] list9;
556 List<? super Object>[] list10;
557 List<String>[] list11;
558 List<? extends String>[] list12;
559 List<? super String>[] list13;
560 final Class<?> clazz = getClass();
561 final Method method = clazz.getMethod("dummyMethod", List.class, List.class, List.class,
562 List.class, List.class, List.class, List.class, List[].class, List[].class,
563 List[].class, List[].class, List[].class, List[].class, List[].class);
564 final Type[] types = method.getGenericParameterTypes();
565
566 delegateBooleanAssertion(types, 0, 0, true);
567 list1 = list0;
568 delegateBooleanAssertion(types, 0, 1, true);
569 list0 = list1;
570 delegateBooleanAssertion(types, 1, 0, true);
571 list2 = list0;
572 delegateBooleanAssertion(types, 0, 2, true);
573 list0 = list2;
574 delegateBooleanAssertion(types, 2, 0, true);
575 list3 = list0;
576 delegateBooleanAssertion(types, 0, 3, true);
577 list0 = list3;
578 delegateBooleanAssertion(types, 3, 0, true);
579 list4 = list0;
580 delegateBooleanAssertion(types, 0, 4, true);
581 list0 = list4;
582 delegateBooleanAssertion(types, 4, 0, true);
583 list5 = list0;
584 delegateBooleanAssertion(types, 0, 5, true);
585 list0 = list5;
586 delegateBooleanAssertion(types, 5, 0, true);
587 list6 = list0;
588 delegateBooleanAssertion(types, 0, 6, true);
589 list0 = list6;
590 delegateBooleanAssertion(types, 6, 0, true);
591
592 delegateBooleanAssertion(types, 1, 1, true);
593 list2 = list1;
594 delegateBooleanAssertion(types, 1, 2, true);
595 list1 = (List<Object>) list2;
596 delegateBooleanAssertion(types, 2, 1, false);
597 list3 = list1;
598 delegateBooleanAssertion(types, 1, 3, true);
599 list1 = (List<Object>) list3;
600 delegateBooleanAssertion(types, 3, 1, false);
601
602 delegateBooleanAssertion(types, 1, 4, false);
603
604 delegateBooleanAssertion(types, 4, 1, false);
605
606 delegateBooleanAssertion(types, 1, 5, false);
607
608 delegateBooleanAssertion(types, 5, 1, false);
609 list6 = list1;
610 delegateBooleanAssertion(types, 1, 6, true);
611 list1 = (List<Object>) list6;
612 delegateBooleanAssertion(types, 6, 1, false);
613
614 delegateBooleanAssertion(types, 2, 2, true);
615 list2 = list3;
616 delegateBooleanAssertion(types, 2, 3, false);
617 list2 = list4;
618 delegateBooleanAssertion(types, 3, 2, true);
619 list3 = (List<? super Object>) list2;
620 delegateBooleanAssertion(types, 2, 4, false);
621 list2 = list5;
622 delegateBooleanAssertion(types, 4, 2, true);
623 list4 = (List<String>) list2;
624 delegateBooleanAssertion(types, 2, 5, false);
625 list2 = list6;
626 delegateBooleanAssertion(types, 5, 2, true);
627 list5 = (List<? extends String>) list2;
628 delegateBooleanAssertion(types, 2, 6, false);
629
630 delegateBooleanAssertion(types, 6, 2, true);
631 list6 = (List<? super String>) list2;
632 delegateBooleanAssertion(types, 3, 3, true);
633
634 delegateBooleanAssertion(types, 3, 4, false);
635
636 delegateBooleanAssertion(types, 4, 3, false);
637
638 delegateBooleanAssertion(types, 3, 5, false);
639
640 delegateBooleanAssertion(types, 5, 3, false);
641 list6 = list3;
642 delegateBooleanAssertion(types, 3, 6, true);
643 list3 = (List<? super Object>) list6;
644 delegateBooleanAssertion(types, 6, 3, false);
645
646 delegateBooleanAssertion(types, 4, 4, true);
647 list5 = list4;
648 delegateBooleanAssertion(types, 4, 5, true);
649 list4 = (List<String>) list5;
650 delegateBooleanAssertion(types, 5, 4, false);
651 list6 = list4;
652 delegateBooleanAssertion(types, 4, 6, true);
653 list4 = (List<String>) list6;
654 delegateBooleanAssertion(types, 6, 4, false);
655
656 delegateBooleanAssertion(types, 5, 5, true);
657 list6 = (List<? super String>) list5;
658 delegateBooleanAssertion(types, 5, 6, false);
659 list5 = (List<? extends String>) list6;
660 delegateBooleanAssertion(types, 6, 5, false);
661
662 delegateBooleanAssertion(types, 6, 6, true);
663
664
665 delegateBooleanAssertion(types, 7, 7, true);
666 list8 = list7;
667 delegateBooleanAssertion(types, 7, 8, true);
668 list7 = list8;
669 delegateBooleanAssertion(types, 8, 7, true);
670 list9 = list7;
671 delegateBooleanAssertion(types, 7, 9, true);
672 list7 = list9;
673 delegateBooleanAssertion(types, 9, 7, true);
674 list10 = list7;
675 delegateBooleanAssertion(types, 7, 10, true);
676 list7 = list10;
677 delegateBooleanAssertion(types, 10, 7, true);
678 list11 = list7;
679 delegateBooleanAssertion(types, 7, 11, true);
680 list7 = list11;
681 delegateBooleanAssertion(types, 11, 7, true);
682 list12 = list7;
683 delegateBooleanAssertion(types, 7, 12, true);
684 list7 = list12;
685 delegateBooleanAssertion(types, 12, 7, true);
686 list13 = list7;
687 delegateBooleanAssertion(types, 7, 13, true);
688 list7 = list13;
689 delegateBooleanAssertion(types, 13, 7, true);
690
691 delegateBooleanAssertion(types, 8, 8, true);
692 list9 = list8;
693 delegateBooleanAssertion(types, 8, 9, true);
694 list8 = (List<Object>[]) list9;
695 delegateBooleanAssertion(types, 9, 8, false);
696 list10 = list8;
697 delegateBooleanAssertion(types, 8, 10, true);
698 list8 = (List<Object>[]) list10;
699 delegateBooleanAssertion(types, 10, 8, false);
700
701 delegateBooleanAssertion(types, 8, 11, false);
702
703 delegateBooleanAssertion(types, 11, 8, false);
704
705 delegateBooleanAssertion(types, 8, 12, false);
706
707 delegateBooleanAssertion(types, 12, 8, false);
708 list13 = list8;
709 delegateBooleanAssertion(types, 8, 13, true);
710 list8 = (List<Object>[]) list13;
711 delegateBooleanAssertion(types, 13, 8, false);
712
713 delegateBooleanAssertion(types, 9, 9, true);
714 list10 = (List<? super Object>[]) list9;
715 delegateBooleanAssertion(types, 9, 10, false);
716 list9 = list10;
717 delegateBooleanAssertion(types, 10, 9, true);
718 list11 = (List<String>[]) list9;
719 delegateBooleanAssertion(types, 9, 11, false);
720 list9 = list11;
721 delegateBooleanAssertion(types, 11, 9, true);
722 list12 = (List<? extends String>[]) list9;
723 delegateBooleanAssertion(types, 9, 12, false);
724 list9 = list12;
725 delegateBooleanAssertion(types, 12, 9, true);
726 list13 = (List<? super String>[]) list9;
727 delegateBooleanAssertion(types, 9, 13, false);
728 list9 = list13;
729 delegateBooleanAssertion(types, 13, 9, true);
730
731 delegateBooleanAssertion(types, 10, 10, true);
732
733 delegateBooleanAssertion(types, 10, 11, false);
734
735 delegateBooleanAssertion(types, 11, 10, false);
736
737 delegateBooleanAssertion(types, 10, 12, false);
738
739 delegateBooleanAssertion(types, 12, 10, false);
740 list13 = list10;
741 delegateBooleanAssertion(types, 10, 13, true);
742 list10 = (List<? super Object>[]) list13;
743 delegateBooleanAssertion(types, 13, 10, false);
744
745 delegateBooleanAssertion(types, 11, 11, true);
746 list12 = list11;
747 delegateBooleanAssertion(types, 11, 12, true);
748 list11 = (List<String>[]) list12;
749 delegateBooleanAssertion(types, 12, 11, false);
750 list13 = list11;
751 delegateBooleanAssertion(types, 11, 13, true);
752 list11 = (List<String>[]) list13;
753 delegateBooleanAssertion(types, 13, 11, false);
754
755 delegateBooleanAssertion(types, 12, 12, true);
756 list13 = (List<? super String>[]) list12;
757 delegateBooleanAssertion(types, 12, 13, false);
758 list12 = (List<? extends String>[]) list13;
759 delegateBooleanAssertion(types, 13, 12, false);
760
761 delegateBooleanAssertion(types, 13, 13, true);
762 final Type disType = getClass().getField("dis").getGenericType();
763
764
765 final Type datType = getClass().getField("dat").getGenericType();
766 final Type daType = getClass().getField("da").getGenericType();
767 final Type uhderType = getClass().getField("uhder").getGenericType();
768 final Type dingType = getClass().getField("ding").getGenericType();
769 final Type testerType = getClass().getField("tester").getGenericType();
770 final Type tester2Type = getClass().getField("tester2").getGenericType();
771 final Type dat2Type = getClass().getField("dat2").getGenericType();
772 final Type dat3Type = getClass().getField("dat3").getGenericType();
773 dis = dat;
774 assertTrue(TypeUtils.isAssignable(datType, disType));
775
776 assertFalse(TypeUtils.isAssignable(daType, disType));
777 dis = uhder;
778 assertTrue(TypeUtils.isAssignable(uhderType, disType));
779 dis = ding;
780 assertFalse(TypeUtils.isAssignable(dingType, disType),
781 String.format("type %s not assignable to %s!", dingType, disType));
782 dis = tester;
783 assertTrue(TypeUtils.isAssignable(testerType, disType));
784
785 assertFalse(TypeUtils.isAssignable(tester2Type, disType));
786
787 assertFalse(TypeUtils.isAssignable(dat2Type, datType));
788
789 assertFalse(TypeUtils.isAssignable(datType, dat2Type));
790
791 assertFalse(TypeUtils.isAssignable(dat3Type, datType));
792 final char ch = 0;
793 final boolean bo = false;
794 final byte by = 0;
795 final short sh = 0;
796 int in = 0;
797 long lo = 0;
798 final float fl = 0;
799 double du;
800 du = ch;
801 assertTrue(TypeUtils.isAssignable(char.class, double.class));
802 du = by;
803 assertTrue(TypeUtils.isAssignable(byte.class, double.class));
804 du = sh;
805 assertTrue(TypeUtils.isAssignable(short.class, double.class));
806 du = in;
807 assertTrue(TypeUtils.isAssignable(int.class, double.class));
808 du = lo;
809 assertTrue(TypeUtils.isAssignable(long.class, double.class));
810 du = fl;
811 assertTrue(TypeUtils.isAssignable(float.class, double.class));
812 lo = in;
813 assertTrue(TypeUtils.isAssignable(int.class, long.class));
814 lo = Integer.valueOf(0);
815 assertTrue(TypeUtils.isAssignable(Integer.class, long.class));
816
817 assertFalse(TypeUtils.isAssignable(int.class, Long.class));
818
819 assertFalse(TypeUtils.isAssignable(Integer.class, Long.class));
820 in = Integer.valueOf(0);
821 assertTrue(TypeUtils.isAssignable(Integer.class, int.class));
822 final Integer inte = in;
823 assertTrue(TypeUtils.isAssignable(int.class, Integer.class));
824 assertTrue(TypeUtils.isAssignable(int.class, Number.class));
825 assertTrue(TypeUtils.isAssignable(int.class, Object.class));
826 final Type intComparableType = getClass().getField("intComparable").getGenericType();
827 intComparable = 1;
828 assertTrue(TypeUtils.isAssignable(int.class, intComparableType));
829 assertTrue(TypeUtils.isAssignable(int.class, Comparable.class));
830 final Serializable ser = 1;
831 assertTrue(TypeUtils.isAssignable(int.class, Serializable.class));
832 final Type longComparableType = getClass().getField("longComparable").getGenericType();
833
834 assertFalse(TypeUtils.isAssignable(int.class, longComparableType));
835
836 assertFalse(TypeUtils.isAssignable(Integer.class, longComparableType));
837
838
839 assertFalse(TypeUtils.isAssignable(int[].class, long[].class));
840 final Integer[] ia = null;
841 final Type caType = getClass().getField("intWildcardComparable").getGenericType();
842 intWildcardComparable = ia;
843 assertTrue(TypeUtils.isAssignable(Integer[].class, caType));
844
845 assertFalse(TypeUtils.isAssignable(Integer[].class, int[].class));
846 final int[] ina = null;
847 final Object[] oa;
848
849 assertFalse(TypeUtils.isAssignable(int[].class, Object[].class));
850 oa = new Integer[0];
851 assertTrue(TypeUtils.isAssignable(Integer[].class, Object[].class));
852 final Type bClassType = AClass.class.getField("bClass").getGenericType();
853 final Type cClassType = AClass.class.getField("cClass").getGenericType();
854 final Type dClassType = AClass.class.getField("dClass").getGenericType();
855 final Type eClassType = AClass.class.getField("eClass").getGenericType();
856 final Type fClassType = AClass.class.getField("fClass").getGenericType();
857 final AClass aClass = new AClass(new AAClass<>());
858 aClass.bClass = aClass.cClass;
859 assertTrue(TypeUtils.isAssignable(cClassType, bClassType));
860 aClass.bClass = aClass.dClass;
861 assertTrue(TypeUtils.isAssignable(dClassType, bClassType));
862 aClass.bClass = aClass.eClass;
863 assertTrue(TypeUtils.isAssignable(eClassType, bClassType));
864 aClass.bClass = aClass.fClass;
865 assertTrue(TypeUtils.isAssignable(fClassType, bClassType));
866 aClass.cClass = aClass.dClass;
867 assertTrue(TypeUtils.isAssignable(dClassType, cClassType));
868 aClass.cClass = aClass.eClass;
869 assertTrue(TypeUtils.isAssignable(eClassType, cClassType));
870 aClass.cClass = aClass.fClass;
871 assertTrue(TypeUtils.isAssignable(fClassType, cClassType));
872 aClass.dClass = aClass.eClass;
873 assertTrue(TypeUtils.isAssignable(eClassType, dClassType));
874 aClass.dClass = aClass.fClass;
875 assertTrue(TypeUtils.isAssignable(fClassType, dClassType));
876 aClass.eClass = aClass.fClass;
877 assertTrue(TypeUtils.isAssignable(fClassType, eClassType));
878 }
879
880 private void testIsAssignable(final Class testUnassignableClass) {
881 final Class<Constructor> rawClass = Constructor.class;
882 final Class<Insets> typeArgClass = Insets.class;
883
884 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
885 assertEquals(rawClass, paramType.getRawType());
886 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
887
888 assertFalse(testUnassignableClass.isAssignableFrom(paramType.getClass()));
889 assertFalse(paramType.getClass().isAssignableFrom(testUnassignableClass));
890
891 final GenericArrayType arrayType = TypeUtils.genericArrayType(paramType);
892 assertFalse(TypeUtils.isAssignable(arrayType, paramType),
893 () -> String.format("TypeUtils.isAssignable(%s, %s)", arrayType, paramType));
894 assertFalse(TypeUtils.isAssignable(paramType, arrayType),
895 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, arrayType));
896 }
897
898 @Test
899 public void testIsAssignableGenericArrayTypeToObject() {
900 final Class<Constructor> rawClass = Constructor.class;
901 final Class<Insets> typeArgClass = Insets.class;
902
903 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
904 assertEquals(rawClass, paramType.getRawType());
905 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
906
907 assertTrue(Object.class.isAssignableFrom(paramType.getClass()));
908 assertFalse(paramType.getClass().isAssignableFrom(Object.class));
909
910 final Type testType = Object.class;
911 assertTrue(TypeUtils.isAssignable(paramType, testType),
912 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
913 assertFalse(TypeUtils.isAssignable(testType, paramType),
914 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
915 }
916
917 @Test
918 public void testIsAssignableGenericArrayTypeToParameterizedType() {
919 final Class<Constructor> rawClass = Constructor.class;
920 final Class<Insets> typeArgClass = Insets.class;
921
922 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
923 assertEquals(rawClass, paramType.getRawType());
924 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
925
926 assertFalse(GenericArrayType.class.isAssignableFrom(paramType.getClass()));
927 assertFalse(paramType.getClass().isAssignableFrom(GenericArrayType.class));
928
929 final GenericArrayType testType = TypeUtils.genericArrayType(paramType);
930 assertFalse(TypeUtils.isAssignable(paramType, testType),
931 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
932 assertFalse(TypeUtils.isAssignable(testType, paramType),
933 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
934 }
935
936 @Test
937 @Disabled("TODO")
938 public void testIsAssignableGenericArrayTypeToWildercardType() {
939 final Class<Constructor> rawClass = Constructor.class;
940 final Class<Insets> typeArgClass = Insets.class;
941
942 final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
943 assertEquals(rawClass, paramType.getRawType());
944 assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
945
946 assertFalse(WildcardType.class.isAssignableFrom(paramType.getClass()));
947 assertFalse(paramType.getClass().isAssignableFrom(WildcardType.class));
948
949 final WildcardType testType = TypeUtils.WILDCARD_ALL;
950
951
952 assertFalse(TypeUtils.isAssignable(paramType, testType),
953 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
954 assertFalse(TypeUtils.isAssignable(testType, paramType),
955 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
956 }
957
958 @SuppressWarnings("boxing")
959 @Test
960 public void testIsInstance() throws SecurityException, NoSuchFieldException {
961 final Type intComparableType = getClass().getField("intComparable").getGenericType();
962 final Type uriComparableType = getClass().getField("uriComparable").getGenericType();
963 intComparable = 1;
964 assertTrue(TypeUtils.isInstance(1, intComparableType));
965
966 assertFalse(TypeUtils.isInstance(1, uriComparableType));
967 }
968
969 @Test
970 public void testLowerBoundedWildcardType() {
971 final WildcardType lowerBounded = TypeUtils.wildcardType().withLowerBounds(java.sql.Date.class).build();
972 assertEquals(String.format("? super %s", java.sql.Date.class.getName()), TypeUtils.toString(lowerBounded));
973 assertEquals(String.format("? super %s", java.sql.Date.class.getName()), lowerBounded.toString());
974
975 final TypeVariable<Class<Iterable>> iterableT0 = Iterable.class.getTypeParameters()[0];
976 final WildcardType lowerTypeVariable = TypeUtils.wildcardType().withLowerBounds(iterableT0).build();
977 assertEquals(String.format("? super %s", iterableT0.getName()), TypeUtils.toString(lowerTypeVariable));
978 assertEquals(String.format("? super %s", iterableT0.getName()), lowerTypeVariable.toString());
979 }
980
981 @Test
982 public void testParameterize() throws Exception {
983 final ParameterizedType stringComparableType = TypeUtils.parameterize(Comparable.class, String.class);
984 assertTrue(TypeUtils.equals(getClass().getField("stringComparable").getGenericType(),
985 stringComparableType));
986 assertEquals("java.lang.Comparable<java.lang.String>", stringComparableType.toString());
987 }
988
989 @Test
990 public void testParameterizeNarrowerTypeArray() {
991 final TypeVariable<?>[] variables = ArrayList.class.getTypeParameters();
992 final ParameterizedType parameterizedType = TypeUtils.parameterize(ArrayList.class, variables);
993 final Map<TypeVariable<?>, Type> mapping = Collections.<TypeVariable<?>, Type>singletonMap(variables[0], String.class);
994 final Type unrolled = TypeUtils.unrollVariables(mapping, parameterizedType);
995 assertEquals(TypeUtils.parameterize(ArrayList.class, String.class), unrolled);
996 }
997
998 @Test
999 public void testParameterizeNullPointerException() {
1000 assertThrows(NullPointerException.class, () -> TypeUtils.parameterize(null, Collections.emptyMap()));
1001 final Map<TypeVariable<?>, Type> nullTypeVariableMap = null;
1002 assertThrows(NullPointerException.class, () -> TypeUtils.parameterize(String.class, nullTypeVariableMap));
1003 }
1004
1005 @Test
1006 public void testParameterizeVarArgsNullPointerException() {
1007 assertThrows(NullPointerException.class, () -> TypeUtils.parameterize(null));
1008 }
1009
1010 @Test
1011 public void testParameterizeWithOwner() throws Exception {
1012 final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
1013 final ParameterizedType dat2Type = TypeUtils.parameterizeWithOwner(owner, That.class, String.class, String.class);
1014 assertTrue(TypeUtils.equals(getClass().getField("dat2").getGenericType(), dat2Type));
1015 }
1016
1017 @Test
1018 public void testParameterizeWithOwner3ArgsNullPointerException() {
1019 final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
1020 assertThrows(NullPointerException.class, () -> TypeUtils.parameterizeWithOwner(owner, null, String.class));
1021 final Map<TypeVariable<?>, Type> nullTypeVariableMap = null;
1022 assertThrows(NullPointerException.class, () -> TypeUtils.parameterizeWithOwner(owner, That.class, nullTypeVariableMap));
1023 }
1024
1025 @Test
1026 public void testParameterizeWithOwnerVarArgsNullPointerException() {
1027 final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
1028 assertThrows(NullPointerException.class, () -> TypeUtils.parameterizeWithOwner(owner, null));
1029 }
1030
1031 @Test
1032 public void testToLongString() {
1033 assertEquals(getClass().getName() + ":B", TypeUtils.toLongString(getClass().getTypeParameters()[0]));
1034
1035 assertThrows(NullPointerException.class, () -> TypeUtils.toLongString(null));
1036 }
1037
1038 @Test
1039 public void testToString_LANG_1311() {
1040 assertEquals("int[]", TypeUtils.toString(int[].class));
1041 assertEquals("java.lang.Integer[]", TypeUtils.toString(Integer[].class));
1042 final Field stringListField = FieldUtils.getDeclaredField(getClass(), "stringListArray");
1043 assertEquals("java.util.List<java.lang.String>[]", TypeUtils.toString(stringListField.getGenericType()));
1044 }
1045
1046 @Test
1047 public void testTypesSatisfyVariables() throws SecurityException,
1048 NoSuchMethodException {
1049 final Map<TypeVariable<?>, Type> typeVarAssigns = new HashMap<>();
1050 final Integer max = TypeUtilsTest.<Integer>stub();
1051 typeVarAssigns.put(getClass().getMethod("stub").getTypeParameters()[0], Integer.class);
1052 assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
1053 typeVarAssigns.clear();
1054 typeVarAssigns.put(getClass().getMethod("stub2").getTypeParameters()[0], Integer.class);
1055 assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
1056 typeVarAssigns.clear();
1057 typeVarAssigns.put(getClass().getMethod("stub3").getTypeParameters()[0], Integer.class);
1058 assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
1059
1060 assertThrows(NullPointerException.class, () -> TypeUtils.typesSatisfyVariables(null));
1061 }
1062
1063 @Test
1064 public void testUnboundedWildcardType() {
1065 final WildcardType unbounded = TypeUtils.wildcardType().withLowerBounds((Type) null).withUpperBounds().build();
1066 assertTrue(TypeUtils.equals(TypeUtils.WILDCARD_ALL, unbounded));
1067 assertArrayEquals(new Type[] { Object.class }, TypeUtils.getImplicitUpperBounds(unbounded));
1068 assertArrayEquals(new Type[] { null }, TypeUtils.getImplicitLowerBounds(unbounded));
1069 assertEquals("?", TypeUtils.toString(unbounded));
1070 assertEquals("?", unbounded.toString());
1071
1072 assertThrows(NullPointerException.class,
1073 () -> TypeUtils.getImplicitLowerBounds(null));
1074 assertThrows(NullPointerException.class,
1075 () -> TypeUtils.getImplicitUpperBounds(null));
1076 }
1077
1078 @Test
1079 public void testWildcardType() throws Exception {
1080 final WildcardType simpleWildcard = TypeUtils.wildcardType().withUpperBounds(String.class).build();
1081 final Field cClass = AClass.class.getField("cClass");
1082 assertTrue(TypeUtils.equals(((ParameterizedType) cClass.getGenericType()).getActualTypeArguments()[0],
1083 simpleWildcard));
1084 assertEquals(String.format("? extends %s", String.class.getName()), TypeUtils.toString(simpleWildcard));
1085 assertEquals(String.format("? extends %s", String.class.getName()), simpleWildcard.toString());
1086 }
1087
1088 @Test
1089 public void testWrap() {
1090 final Type t = getClass().getTypeParameters()[0];
1091 assertTrue(TypeUtils.equals(t, TypeUtils.wrap(t).getType()));
1092
1093 assertEquals(String.class, TypeUtils.wrap(String.class).getType());
1094 }
1095 }