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