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