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.juneau.reflect;
18  
19  import static java.lang.annotation.ElementType.*;
20  import static java.lang.annotation.RetentionPolicy.*;
21  import static org.apache.juneau.Context.*;
22  import static org.apache.juneau.TestUtils.*;
23  import static org.apache.juneau.reflect.ClassInfo.*;
24  import static org.apache.juneau.reflect.ReflectFlags.*;
25  import static org.junit.jupiter.api.Assertions.*;
26  
27  import java.io.*;
28  import java.lang.annotation.*;
29  import java.lang.reflect.*;
30  import java.util.*;
31  import java.util.function.*;
32  import java.util.stream.*;
33  
34  import org.apache.juneau.*;
35  import org.apache.juneau.annotation.*;
36  import org.apache.juneau.svl.*;
37  import org.junit.jupiter.api.*;
38  
39  public class ClassInfo_Test extends TestBase {
40  
41  	@Documented
42  	@Target(TYPE)
43  	@Retention(RUNTIME)
44  	@Inherited
45  	public static @interface A {
46  		int value();
47  	}
48  
49  	@Documented
50  	@Target(TYPE)
51  	@Retention(RUNTIME)
52  	@Inherited
53  	public static @interface B {
54  		int value();
55  	}
56  
57  	@Documented
58  	@Target(TYPE)
59  	@Retention(RUNTIME)
60  	@Inherited
61  	@ContextApply(AConfigApply.class)
62  	static @interface AConfig {
63  		int value();
64  	}
65  
66  	public static class AConfigApply extends AnnotationApplier<AConfig,Context.Builder> {
67  		protected AConfigApply(VarResolverSession vr) {
68  			super(AConfig.class, Context.Builder.class, vr);
69  		}
70  		@Override
71  		public void apply(AnnotationInfo<AConfig> a, Context.Builder b) {}  // NOSONAR
72  	}
73  
74  	private static void check(String expected, Object o) {
75  		if (o instanceof List) {
76  			var l = (List<?>)o;
77  			String actual = l
78  				.stream()
79  				.map(TO_STRING)
80  				.collect(Collectors.joining(","));
81  			assertEquals(expected, actual);
82  		} else if (o instanceof Iterable) {
83  			var actual = StreamSupport.stream(((Iterable<?>)o).spliterator(), false)
84  				.map(TO_STRING)
85  				.collect(Collectors.joining(","));
86  			assertEquals(expected, actual);
87  		} else {
88  			assertEquals(expected, TO_STRING.apply(o));
89  		}
90  	}
91  
92  	private static final Function<Object,String> TO_STRING = t -> {
93  		if (t == null)
94  			return null;
95  		if (t instanceof Class)
96  			return ((Class<?>)t).getSimpleName();
97  		if (t instanceof Package)
98  			return ((Package)t).getName();
99  		if (t instanceof ClassInfo)
100 			return ((ClassInfo)t).getSimpleName();
101 		if (t instanceof MethodInfo)
102 			return ((MethodInfo)t).getDeclaringClass().getSimpleName() + '.' + ((MethodInfo)t).getShortName();
103 		if (t instanceof ConstructorInfo)
104 			return ((ConstructorInfo)t).getShortName();
105 		if (t instanceof FieldInfo)
106 			return ((FieldInfo)t).getDeclaringClass().getSimpleName() + '.' + ((FieldInfo)t).getName();
107 		if (t instanceof A)
108 			return "@A(" + ((A)t).value() + ")";
109 		if (t instanceof PA)
110 			return "@PA(" + ((PA)t).value() + ")";
111 		if (t instanceof AConfig)
112 			return "@AConfig(" + ((AConfig)t).value() + ")";
113 		if (t instanceof AnnotationInfo)
114 			return ClassInfo_Test.TO_STRING.apply(((AnnotationInfo<?>)t).inner());
115 		if (t instanceof AnnotationList) {
116 			AnnotationList al = (AnnotationList)t;
117 			return al.toString();
118 		}
119 		return t.toString();
120 	};
121 
122 	//-----------------------------------------------------------------------------------------------------------------
123 	// Initialization
124 	//-----------------------------------------------------------------------------------------------------------------
125 
126 	public class A1 {}
127 	public class A2 extends Value<A1>{}
128 	public class A3 extends Value<Map<String,List<String>>>{}
129 	public class A4 extends Value<Map<String,String[][]>>{}
130 	public static Type aType, pType, pTypeDimensional, pTypeGeneric, pTypeGenericArg;
131 	static {
132 		aType = ((ParameterizedType)A2.class.getGenericSuperclass()).getActualTypeArguments()[0];
133 		pType = ((ParameterizedType)A3.class.getGenericSuperclass()).getActualTypeArguments()[0];
134 		pTypeDimensional = ((ParameterizedType)A4.class.getGenericSuperclass()).getActualTypeArguments()[0];
135 		pTypeGeneric = HashMap.class.getGenericSuperclass();
136 		pTypeGenericArg = ((ParameterizedType)pTypeGeneric).getActualTypeArguments()[1];
137 	}
138 
139 	static ClassInfo aTypeInfo=of(aType), pTypeInfo=of(pType), pTypeDimensionalInfo=of(pTypeDimensional), pTypeGenericInfo=of(pTypeGeneric), pTypeGenericArgInfo=of(pTypeGenericArg);
140 	static ClassInfo aClass=of(AClass.class), aInterface=of(AInterface.class);
141 
142 	@Test void ofType() {
143 		check("A1", of(A1.class));
144 		check("A1", of(aType));
145 		check("Map", pTypeInfo);
146 		check("Map", pTypeDimensionalInfo);
147 		check("AbstractMap", pTypeGenericInfo);
148 		check("V", pTypeGenericArgInfo);
149 	}
150 
151 	@Test void ofTypeOnObject() {
152 		check("A1", of(new A1()));
153 	}
154 
155 	@Test void ofTypeOnNulls() {
156 		check(null, of((Class<?>)null));
157 		check(null, of((Type)null));
158 		check(null, of((Object)null));
159 	}
160 
161 	@Test void inner() {
162 		assertNotNull(of(A1.class).inner());
163 		assertTrue(of(A1.class).innerType() instanceof Class);
164 	}
165 
166 	@Test void resolved() {
167 		check("A1", of(A1.class).unwrap(Value.class));
168 		check("A1", of(A2.class).unwrap(Value.class));
169 	}
170 
171 	public static class A6 {
172 		public Optional<A1> m1(Optional<A1> bar) {
173 			return null;
174 		}
175 		public Value<A1> m2(Value<A1> bar) {
176 			return null;
177 		}
178 	}
179 
180 	@Test void resolvedParams() {
181 		var mi2 = ClassInfo.of(A6.class).getPublicMethod(x -> x.hasName("m1"));
182 		check("A1", mi2.getParamType(0).unwrap(Optional.class));
183 		check("A1", mi2.getReturnType().unwrap(Optional.class));
184 		mi2 = ClassInfo.of(A6.class).getPublicMethod(x -> x.hasName("m2"));
185 		check("A1", mi2.getParamType(0).unwrap(Value.class));
186 		check("A1", mi2.getReturnType().unwrap(Value.class));
187 	}
188 
189 	//-----------------------------------------------------------------------------------------------------------------
190 	// Parent classes and interfaces.
191 	//-----------------------------------------------------------------------------------------------------------------
192 
193 	interface BI1 {}
194 	interface BI2 extends BI1 {}
195 	interface BI3 {}
196 	interface BI4 {}
197 	@SuppressWarnings("unused") static class BC1 implements BI1, BI2 {}
198 	static class BC2 extends BC1 implements BI3 {}
199 	static class BC3 extends BC2 {}
200 
201 	static ClassInfo bi1=of(BI1.class), bi2=of(BI2.class), bi3=of(BI3.class), bi4=of(BI4.class), bc1=of(BC1.class), bc2=of(BC2.class), bc3=of(BC3.class), object=of(Object.class);
202 
203 	@Test void getDeclaredInterfaces() {
204 		check("", bi4.getDeclaredInterfaces());
205 		check("BI1,BI2", bc1.getDeclaredInterfaces());
206 		check("BI3", bc2.getDeclaredInterfaces());
207 		check("", bc3.getDeclaredInterfaces());
208 	}
209 
210 	@Test void getDeclaredInterfaces_onType() {
211 		check("", aTypeInfo.getDeclaredInterfaces());
212 		check("", pTypeInfo.getDeclaredInterfaces());
213 		check("", pTypeDimensionalInfo.getDeclaredInterfaces());
214 		check("Map", pTypeGenericInfo.getDeclaredInterfaces());
215 		check("", pTypeGenericArgInfo.getDeclaredInterfaces());
216 	}
217 
218 	@Test void getDeclaredInterfaces_twice() {
219 		check("BI1,BI2", bc1.getDeclaredInterfaces());
220 		check("BI1,BI2", bc1.getDeclaredInterfaces());
221 	}
222 
223 	@Test void getInterfaces() {
224 		check("", bi4.getInterfaces());
225 		check("BI1,BI2", bc1.getInterfaces());
226 		check("BI3,BI1,BI2", bc2.getInterfaces());
227 		check("BI3,BI1,BI2", bc3.getInterfaces());
228 	}
229 
230 	@Test void getInterfaces_tiwce() {
231 		check("BI3,BI1,BI2", bc2.getInterfaces());
232 		check("BI3,BI1,BI2", bc2.getInterfaces());
233 	}
234 
235 	@Test void getParents() {
236 		check("BC3,BC2,BC1", bc3.getParents());
237 		check("", object.getParents());
238 		check("BI1", bi1.getParents());
239 	}
240 
241 	@Test void getAllParents() {
242 		check("BC3,BC2,BC1,BI3,BI1,BI2", bc3.getAllParents());
243 		check("", object.getAllParents());
244 		check("BI1", bi1.getAllParents());
245 	}
246 
247 	@Test void getAllParents_twice() {
248 		check("BC3,BC2,BC1,BI3,BI1,BI2", bc3.getAllParents());
249 		check("BC3,BC2,BC1,BI3,BI1,BI2", bc3.getAllParents());
250 	}
251 
252 	@Test void getParent() {
253 		check("BC2", bc3.getSuperclass());
254 		check("BC1", bc2.getSuperclass());
255 		check("Object", bc1.getSuperclass());
256 		check(null, object.getSuperclass());
257 		check(null, bi2.getSuperclass());
258 		check(null, bi1.getSuperclass());
259 	}
260 
261 	@Test void getParent_onType() {
262 		check("Object", aTypeInfo.getSuperclass());
263 		check(null, pTypeInfo.getSuperclass());
264 		check(null, pTypeDimensionalInfo.getSuperclass());
265 		check("Object", pTypeGenericInfo.getSuperclass());
266 		check(null, pTypeGenericArgInfo.getSuperclass());
267 	}
268 
269 	//-----------------------------------------------------------------------------------------------------------------
270 	// Methods
271 	//-----------------------------------------------------------------------------------------------------------------
272 
273 	interface CI1 {
274 		void i1a();
275 		void i1b();
276 	}
277 	interface CI2 extends CI1 {
278 		void i2b();
279 		void i2a();
280 	}
281 	interface CI3 {}
282 	interface CI4 {}
283 	@SuppressWarnings("unused") abstract static class CC1 implements CI1, CI2 {
284 		@Override
285 		public void i1a() {}
286 		protected void c1b() {}
287 		public void c1a() {}
288 	}
289 	static class CC2 extends CC1 implements CI3 {
290 		public void c2b() {}  // NOSONAR
291 		@Override
292 		public void i1b() {}  // NOSONAR
293 		@Override
294 		public void i2b() {}  // NOSONAR
295 		@Override
296 		public void i2a() {}  // NOSONAR
297 		protected void c2a() {}  // NOSONAR
298 	}
299 	static class CC3 extends CC2 {
300 		@Override
301 		public void i2b() {}  // NOSONAR
302 		public void c3a() {}  // NOSONAR
303 		protected void c3b() {}  // NOSONAR
304 	}
305 	static ClassInfo cc3 = of(CC3.class), ci2 = of(CI2.class);
306 
307 	@Test void getPublicMethods() {
308 		check("CC3.c1a(),CC3.c2b(),CC3.c3a(),CC3.i1a(),CC3.i1b(),CC3.i2a(),CC3.i2b()", cc3.getPublicMethods());
309 		check("CI2.i1a(),CI2.i1b(),CI2.i2a(),CI2.i2b()", ci2.getPublicMethods());
310 	}
311 
312 	@Test void getPublicMethods_twice() {
313 		check("CI2.i1a(),CI2.i1b(),CI2.i2a(),CI2.i2b()", ci2.getPublicMethods());
314 		check("CI2.i1a(),CI2.i1b(),CI2.i2a(),CI2.i2b()", ci2.getPublicMethods());
315 	}
316 
317 	@Test void getPublicMethods_onType() {
318 		check("", aTypeInfo.getPublicMethods());
319 		check("", pTypeGenericArgInfo.getPublicMethods());
320 	}
321 
322 	@Test void getAllMethods() {
323 		check("CC3.c3a(),CC3.c3b(),CC3.i2b(),CC2.c2a(),CC2.c2b(),CC2.i1b(),CC2.i2a(),CC2.i2b(),CC1.c1a(),CC1.c1b(),CC1.i1a(),CI1.i1a(),CI1.i1b(),CI2.i2a(),CI2.i2b()", cc3.getMethods());
324 	}
325 
326 	@Test void getAllMethods_twice() {
327 		check("CC3.c3a(),CC3.c3b(),CC3.i2b(),CC2.c2a(),CC2.c2b(),CC2.i1b(),CC2.i2a(),CC2.i2b(),CC1.c1a(),CC1.c1b(),CC1.i1a(),CI1.i1a(),CI1.i1b(),CI2.i2a(),CI2.i2b()", cc3.getMethods());
328 		check("CC3.c3a(),CC3.c3b(),CC3.i2b(),CC2.c2a(),CC2.c2b(),CC2.i1b(),CC2.i2a(),CC2.i2b(),CC1.c1a(),CC1.c1b(),CC1.i1a(),CI1.i1a(),CI1.i1b(),CI2.i2a(),CI2.i2b()", cc3.getMethods());
329 	}
330 
331 	@Test void getDeclaredMethods() {
332 		check("CC3.c3a(),CC3.c3b(),CC3.i2b()", cc3.getDeclaredMethods());
333 		check("CI2.i2a(),CI2.i2b()", ci2.getDeclaredMethods());
334 		check("CI2.i2a(),CI2.i2b()", ci2.getDeclaredMethods());
335 	}
336 
337 	@Test void getDeclaredMethods_twice() {
338 		check("CI2.i2a(),CI2.i2b()", ci2.getDeclaredMethods());
339 		check("CI2.i2a(),CI2.i2b()", ci2.getDeclaredMethods());
340 	}
341 
342 	@Test void getDeclaredMethods_onType() {
343 		check("", aTypeInfo.getDeclaredMethods());
344 		check("", pTypeGenericArgInfo.getDeclaredMethods());
345 	}
346 
347 	//-----------------------------------------------------------------------------------------------------------------
348 	// Constructors
349 	//-----------------------------------------------------------------------------------------------------------------
350 
351 	static class E1 {
352 		public E1() {}
353 		public E1(String a) {}  // NOSONAR
354 		public E1(Writer a) {}  // NOSONAR
355 		public E1(String a, Writer b) {}  // NOSONAR
356 		protected E1(int a) {}  // NOSONAR
357 		E1(float a) {}  // NOSONAR
358 	}
359 	static class E2 {
360 		protected E2() {}
361 	}
362 	abstract static class E3 {
363 		public E3() {}
364 	}
365 	class E4 {
366 		public E4() {}  // NOSONAR
367 	}
368 	static class E5 {
369 		@Deprecated
370 		public E5() {}  // NOSONAR
371 	}
372 	class E6 {
373 		public E6(String a) {}
374 	}
375 	static ClassInfo e1=of(E1.class), e2=of(E2.class), e3=of(E3.class), e4=of(E4.class), e5=of(E5.class), e6=of(E6.class);
376 
377 	@Test void getPublicConstructors() {
378 		check("E1(),E1(Writer),E1(String),E1(String,Writer)", e1.getPublicConstructors());
379 	}
380 
381 	@Test void getPublicConstructors_twice() {
382 		check("E1(),E1(Writer),E1(String),E1(String,Writer)", e1.getPublicConstructors());
383 		check("E1(),E1(Writer),E1(String),E1(String,Writer)", e1.getPublicConstructors());
384 	}
385 
386 	@Test void getPublicConstructors_onType() {
387 		check("A1(ClassInfo_Test)", aTypeInfo.getPublicConstructors());
388 		check("", pTypeInfo.getPublicConstructors());
389 		check("", pTypeDimensionalInfo.getPublicConstructors());
390 		check("", pTypeGenericInfo.getPublicConstructors());
391 		check("", pTypeGenericArgInfo.getPublicConstructors());
392 	}
393 
394 	@Test void getDeclaredConstructors() {
395 		check("E1(),E1(float),E1(int),E1(Writer),E1(String),E1(String,Writer)", e1.getDeclaredConstructors());
396 	}
397 
398 	@Test void getDeclaredConstructors_twice() {
399 		check("E1(),E1(float),E1(int),E1(Writer),E1(String),E1(String,Writer)", e1.getDeclaredConstructors());
400 		check("E1(),E1(float),E1(int),E1(Writer),E1(String),E1(String,Writer)", e1.getDeclaredConstructors());
401 	}
402 
403 	@Test void getDeclaredConstructors_onType() {
404 		check("A1(ClassInfo_Test)", aTypeInfo.getDeclaredConstructors());
405 		check("", pTypeInfo.getDeclaredConstructors());
406 		check("", pTypeDimensionalInfo.getDeclaredConstructors());
407 		check("AbstractMap()", pTypeGenericInfo.getDeclaredConstructors());
408 		check("", pTypeGenericArgInfo.getDeclaredConstructors());
409 	}
410 
411 	@Test void getPublicConstructor_classArgs() {
412 		check("E1(String)", e1.getPublicConstructor(x -> x.hasParamTypes(String.class)));
413 	}
414 
415 	@Test void getPublicConstructor_objectArgs() {
416 		check("E1(String)", e1.getPublicConstructor(x -> x.canAccept("foo")));
417 	}
418 
419 	@Test void getNoArgConstructor() {
420 		check("E2()", e2.getNoArgConstructor(Visibility.PRIVATE));
421 		check("E2()", e2.getNoArgConstructor(Visibility.PROTECTED));
422 		check("E2()", e2.getNoArgConstructor(Visibility.DEFAULT));
423 		check(null, e2.getNoArgConstructor(Visibility.PUBLIC));
424 	}
425 
426 	@Test void getNoArgConstructor_abstractClass() {
427 		check(null, e3.getNoArgConstructor(Visibility.PUBLIC));
428 	}
429 
430 	@Test void getNoArgConstructor_innerClass() {
431 		check("E4(ClassInfo_Test)", e4.getNoArgConstructor(Visibility.PUBLIC));
432 	}
433 
434 	@Test void getNoArgConstructor_noConstructor() {
435 		check(null, e6.getNoArgConstructor(Visibility.PUBLIC));
436 	}
437 
438 	@Test void getPublicNoArgConstructor() {
439 		check("E1()", e1.getPublicConstructor(ConstructorInfo::hasNoParams));
440 	}
441 
442 	@Test void getConstructor() {
443 		check("E1(int)", e1.getDeclaredConstructor(x -> x.isVisible(Visibility.PROTECTED) && x.hasParamTypes(int.class)));
444 		check("E1(int)", e1.getDeclaredConstructor(x -> x.isVisible(Visibility.PRIVATE) && x.hasParamTypes(int.class)));
445 		check(null, e1.getDeclaredConstructor(x -> x.isVisible(Visibility.PUBLIC) && x.hasParamTypes(int.class)));
446 		check("E3()", e3.getDeclaredConstructor(x -> x.isVisible(Visibility.PUBLIC)));
447 		check("E4(ClassInfo_Test)", e4.getDeclaredConstructor(x -> x.isVisible(Visibility.PUBLIC)));
448 		check("E5()", e5.getDeclaredConstructor(x -> x.isVisible(Visibility.PUBLIC)));
449 	}
450 
451 	//-----------------------------------------------------------------------------------------------------------------
452 	// Fields
453 	//-----------------------------------------------------------------------------------------------------------------
454 
455 	abstract static class F1 {
456 		public int f1a;
457 		public int f1b;
458 	}
459 	static class F2 extends F1 {
460 		public int f1a;
461 		public int f2b;
462 		@Deprecated int f2c;
463 		protected int f2d;
464 	}
465 	static ClassInfo f1=of(F1.class), f2=of(F2.class);
466 
467 	@Test void getPublicFields() {
468 		check("F2.f1a,F1.f1b,F2.f2b", f2.getPublicFields());
469 	}
470 
471 	@Test void getPublicFields_twice() {
472 		check("F2.f1a,F1.f1b,F2.f2b", f2.getPublicFields());
473 		check("F2.f1a,F1.f1b,F2.f2b", f2.getPublicFields());
474 	}
475 
476 	@Test void getPublicFields_onType() {
477 		check("", aTypeInfo.getPublicFields());
478 	}
479 
480 	@Test void getDeclaredFields() {
481 		check("F2.f1a,F2.f2b,F2.f2c,F2.f2d", f2.getDeclaredFields());
482 	}
483 
484 	@Test void getDeclaredFields_twice() {
485 		check("F2.f1a,F2.f2b,F2.f2c,F2.f2d", f2.getDeclaredFields());
486 		check("F2.f1a,F2.f2b,F2.f2c,F2.f2d", f2.getDeclaredFields());
487 	}
488 
489 	@Test void getDeclaredFields_onType() {
490 		check("A1.this$0", aTypeInfo.getDeclaredFields());
491 		check("", pTypeInfo.getDeclaredFields());
492 		check("", pTypeDimensionalInfo.getDeclaredFields());
493 		check("AbstractMap.keySet,AbstractMap.values", pTypeGenericInfo.getDeclaredFields());
494 		check("", pTypeGenericArgInfo.getDeclaredFields());
495 	}
496 
497 	@Test void getAllFieldsParentFirst() {
498 		check("F1.f1a,F1.f1b,F2.f1a,F2.f2b,F2.f2c,F2.f2d", f2.getAllFields());
499 	}
500 
501 	@Test void getAllFieldsParentFirst_twice() {
502 		check("F1.f1a,F1.f1b,F2.f1a,F2.f2b,F2.f2c,F2.f2d", f2.getAllFields());
503 		check("F1.f1a,F1.f1b,F2.f1a,F2.f2b,F2.f2c,F2.f2d", f2.getAllFields());
504 	}
505 
506 	static class F3 {
507 		public int a1;
508 		int a2;
509 	}
510 	static ClassInfo f3=of(F3.class);
511 
512 	@Test void getPublicField() {
513 		check("F3.a1", f3.getPublicField(x -> x.hasName("a1")));
514 		check(null, f3.getPublicField(x -> x.hasName("a2")));
515 		check(null, f3.getPublicField(x -> x.hasName("a3")));
516 	}
517 
518 	@Test void getDeclaredField() {
519 		check("F3.a1", f3.getDeclaredField(x -> x.hasName("a1")));
520 		check("F3.a2", f3.getDeclaredField(x -> x.hasName("a2")));
521 		check(null, f3.getDeclaredField(x -> x.hasName("a3")));
522 	}
523 
524 	//-----------------------------------------------------------------------------------------------------------------
525 	// Annotations
526 	//-----------------------------------------------------------------------------------------------------------------
527 
528 	@A(1) interface GI1 {}
529 	@A(2) interface GI2 extends GI1 {}
530 	@A(3) interface GI3 {}
531 	@A(4) interface GI4 {}
532 	@SuppressWarnings("unused") @A(5) static class G1 implements GI1, GI2 {}
533 	@A(6) static class G2 extends G1 implements GI3 {}
534 	@A(7) static class G3 extends G2 {}
535 	static class G4 extends G3 {}
536 	static class G5 implements GI3 {}
537 
538 	static ClassInfo g3=of(G3.class), g4=of(G4.class), g5=of(G5.class);
539 
540 	@Test void getAnnotation() {
541 		check("@A(7)", g3.getAnnotation(A.class));
542 		check(null, g3.getAnnotation(B.class));
543 		check(null, g3.getAnnotation(null));
544 	}
545 
546 	@Test void getAnnotation_twice() {
547 		check("@A(7)", g3.getAnnotation(A.class));
548 		check("@A(7)", g3.getAnnotation(A.class));
549 	}
550 
551 	@Test void getAnnotation_onParent() {
552 		check("@A(7)", g4.getAnnotation(A.class));
553 		check(null, g4.getAnnotation(B.class));
554 		check(null, g4.getAnnotation(null));
555 	}
556 
557 	@Test void getAnnotation_onInterface() {
558 		check("@A(3)", g5.getAnnotation(A.class));
559 		check(null, g5.getAnnotation(B.class));
560 		check(null, g5.getAnnotation(null));
561 	}
562 
563 	@Test void hasAnnotation() {
564 		assertTrue(g3.hasAnnotation(A.class));
565 		assertFalse(g3.hasAnnotation(B.class));
566 		assertFalse(g3.hasAnnotation(null));
567 	}
568 
569 	@Test void getAnnotations() {
570 		check("@A(2),@A(1),@A(3),@A(5),@A(6),@A(7)", g3.getAnnotations(A.class));
571 		check("@A(2),@A(1),@A(3),@A(5),@A(6),@A(7)", g4.getAnnotations(A.class));
572 		check("@A(3)", g5.getAnnotations(A.class));
573 	}
574 
575 	@Test void forEachAnnotation() {
576 		var l1 = list();
577 		g3.forEachAnnotation(A.class, null, x -> l1.add(x.value()));
578 		assertList(l1, "2", "1", "3", "5", "6", "7");
579 
580 		var l2 = list();
581 		g4.forEachAnnotation(A.class, null, x -> l2.add(x.value()));
582 		assertList(l2, "2", "1", "3", "5", "6", "7");
583 
584 		var l3 = list();
585 		g5.forEachAnnotation(A.class, null, x -> l3.add(x.value()));
586 		assertList(l3, "3");
587 
588 		var l4 = list();
589 		g3.forEachAnnotation(A.class, x -> x.value() == 5, x -> l4.add(x.value()));
590 		assertList(l4, "5");
591 	}
592 
593 	@Test void firstAnnotation() {
594 		assertEquals(2, g3.firstAnnotation(A.class, null).value());
595 		assertEquals(2, g4.firstAnnotation(A.class, null).value());
596 		assertEquals(3, g5.firstAnnotation(A.class, null).value());
597 		assertEquals(5, g3.firstAnnotation(A.class, x -> x.value() == 5).value());
598 	}
599 	@Test void lastAnnotation() {
600 		assertEquals(7, g3.lastAnnotation(A.class, null).value());
601 		assertEquals(7, g4.lastAnnotation(A.class, null).value());
602 		assertEquals(3, g5.lastAnnotation(A.class, null).value());
603 		assertEquals(5, g3.lastAnnotation(A.class, x -> x.value() == 5).value());
604 	}
605 
606 	@Test void getPackageAnnotation() {
607 		check("@PA(10)", g3.getPackageAnnotation(PA.class));
608 	}
609 
610 	@Test void getPackageAnnotation_onType() {
611 		check("@PA(10)", aTypeInfo.getPackageAnnotation(PA.class));
612 		check(null, pTypeInfo.getPackageAnnotation(PA.class));
613 		check(null, pTypeDimensionalInfo.getPackageAnnotation(PA.class));
614 		check(null, pTypeGenericInfo.getPackageAnnotation(PA.class));
615 		check(null, pTypeGenericArgInfo.getPackageAnnotation(PA.class));
616 	}
617 
618 	@Test void getAnnotationsMapParentFirst() {
619 		check("@PA(10),@A(2),@A(1),@A(3),@A(5),@A(6),@A(7)", g3.getAnnotationList());
620 		check("@PA(10),@A(2),@A(1),@A(3),@A(5),@A(6),@A(7)", g4.getAnnotationList());
621 		check("@PA(10),@A(3)", g5.getAnnotationList());
622 	}
623 
624 	@A(1) @AConfig(1) interface GBI1 {}
625 	@A(2) @AConfig(2) interface GBI2 extends GBI1 {}
626 	@A(3) @AConfig(3) interface GBI3 {}
627 	@A(4) @AConfig(4) interface GBI4 {}
628 	@SuppressWarnings("unused") @A(5) @AConfig(5) static class GB1 implements GBI1, GBI2 {}
629 	@A(6) @AConfig(6) static class GB2 extends GB1 implements GBI3 {}
630 	@A(7) @AConfig(7) static class GB3 extends GB2 {}
631 	static class GB4 extends GB3 {}
632 	static class GB5 implements GBI3 {}
633 
634 	static ClassInfo gb3=of(GB3.class), gb4=of(GB4.class), gb5=of(GB5.class);
635 
636 	@Test void getConfigAnnotationsMapParentFirst() {
637 		check("@AConfig(2),@AConfig(1),@AConfig(3),@AConfig(5),@AConfig(6),@AConfig(7)", gb3.getAnnotationList(CONTEXT_APPLY_FILTER));
638 		check("@AConfig(2),@AConfig(1),@AConfig(3),@AConfig(5),@AConfig(6),@AConfig(7)", gb4.getAnnotationList(CONTEXT_APPLY_FILTER));
639 		check("@AConfig(3)", gb5.getAnnotationList(CONTEXT_APPLY_FILTER));
640 	}
641 
642 	//-----------------------------------------------------------------------------------------------------------------
643 	// Characteristics
644 	//-----------------------------------------------------------------------------------------------------------------
645 
646 	public static class H_Public {}
647 	static class H_Package{}
648 	protected static class H_Protected{}
649 	private static class H_Private{}
650 	public class H_PublicMember {}
651 	public abstract class H_AbstractPublic {}
652 	@Deprecated public class H_PublicDeprecated {}
653 
654 	static ClassInfo hPublic=of(H_Public.class), hPackage=of(H_Package.class), hProtected=of(H_Protected.class), hPrivate=of(H_Private.class), hPublicMember=of(H_PublicMember.class), hAbstractPublic=of(H_AbstractPublic.class), hPublicDeprecated=of(H_PublicDeprecated.class);  // NOSONAR
655 
656 	@Test void isDeprecated() {
657 		assertFalse(hPublic.isDeprecated());
658 		assertTrue(hPublicDeprecated.isDeprecated());
659 	}
660 
661 	@Test void isDeprecated_onType() {
662 		assertFalse(aTypeInfo.isDeprecated());
663 		assertFalse(pTypeGenericArgInfo.isDeprecated());
664 	}
665 
666 	@Test void isNotDeprecated() {
667 		assertTrue(hPublic.isNotDeprecated());
668 		assertFalse(hPublicDeprecated.isNotDeprecated());
669 	}
670 
671 	@Test void isNotDeprecated_onType() {
672 		assertTrue(aTypeInfo.isNotDeprecated());
673 		assertTrue(pTypeInfo.isNotDeprecated());
674 		assertTrue(pTypeDimensionalInfo.isNotDeprecated());
675 		assertTrue(pTypeGenericInfo.isNotDeprecated());
676 		assertTrue(pTypeGenericArgInfo.isNotDeprecated());
677 	}
678 
679 	@Test void isPublic() {
680 		assertTrue(hPublic.isPublic());
681 		assertFalse(hProtected.isPublic());
682 		assertFalse(hPackage.isPublic());
683 		assertFalse(hPrivate.isPublic());
684 	}
685 
686 	@Test void isPublic_onType() {
687 		assertTrue(aTypeInfo.isPublic());
688 		assertTrue(pTypeInfo.isPublic());
689 		assertTrue(pTypeDimensionalInfo.isPublic());
690 		assertTrue(pTypeGenericInfo.isPublic());
691 		assertFalse(pTypeGenericArgInfo.isPublic());
692 	}
693 
694 	@Test void isNotPublic() {
695 		assertFalse(hPublic.isNotPublic());
696 		assertTrue(hProtected.isNotPublic());
697 		assertTrue(hPackage.isNotPublic());
698 		assertTrue(hPrivate.isNotPublic());
699 	}
700 
701 	@Test void isNotPublic_onType() {
702 		assertFalse(aTypeInfo.isNotPublic());
703 		assertTrue(pTypeGenericArgInfo.isNotPublic());
704 	}
705 
706 	@Test void isStatic() {
707 		assertTrue(hPublic.isStatic());
708 		assertFalse(hPublicMember.isStatic());
709 	}
710 
711 	@Test void isStatic_onType() {
712 		assertFalse(aTypeInfo.isStatic());
713 		assertFalse(pTypeGenericArgInfo.isStatic());
714 	}
715 
716 	@Test void isNotStatic() {
717 		assertFalse(hPublic.isNotStatic());
718 		assertTrue(hPublicMember.isNotStatic());
719 	}
720 
721 	@Test void isNotStatic_onType() {
722 		assertTrue(aTypeInfo.isNotStatic());
723 		assertTrue(pTypeInfo.isNotStatic());
724 		assertTrue(pTypeDimensionalInfo.isNotStatic());
725 		assertTrue(pTypeGenericInfo.isNotStatic());
726 		assertTrue(pTypeGenericArgInfo.isNotStatic());
727 	}
728 
729 	@Test void isAbstract() {
730 		assertTrue(hAbstractPublic.isAbstract());
731 		assertFalse(pTypeGenericArgInfo.isAbstract());
732 	}
733 
734 	@Test void isAbstract_onType() {
735 		assertFalse(aTypeInfo.isAbstract());
736 		assertFalse(aTypeInfo.isAbstract());
737 	}
738 
739 	@Test void isNotAbstract() {
740 		assertFalse(hAbstractPublic.isNotAbstract());
741 		assertTrue(hPublic.isNotAbstract());
742 	}
743 
744 	@Test void isNotAbstract_onType() {
745 		assertTrue(aTypeInfo.isNotAbstract());
746 		assertFalse(pTypeInfo.isNotAbstract());
747 		assertFalse(pTypeDimensionalInfo.isNotAbstract());
748 		assertFalse(pTypeGenericInfo.isNotAbstract());
749 		assertTrue(pTypeGenericArgInfo.isNotAbstract());
750 	}
751 
752 	@Test void isMemberClass() {
753 		assertTrue(hPublic.isMemberClass());
754 		assertTrue(hPublicMember.isMemberClass());
755 		assertFalse(aClass.isMemberClass());
756 		assertFalse(aInterface.isMemberClass());
757 	}
758 
759 	@Test void isMemberClass_onType() {
760 		assertTrue(aTypeInfo.isMemberClass());
761 		assertFalse(pTypeInfo.isMemberClass());
762 		assertFalse(pTypeDimensionalInfo.isMemberClass());
763 		assertFalse(pTypeGenericInfo.isMemberClass());
764 		assertFalse(pTypeGenericArgInfo.isMemberClass());
765 	}
766 
767 	@Test void isNotMemberClass() {
768 		assertFalse(hPublic.isNotMemberClass());
769 		assertFalse(hPublicMember.isNotMemberClass());
770 		assertTrue(aClass.isNotMemberClass());
771 		assertTrue(aInterface.isNotMemberClass());
772 	}
773 
774 	@Test void isNotMemberClass_onType() {
775 		assertFalse(aTypeInfo.isNotMemberClass());
776 		assertTrue(pTypeGenericArgInfo.isNotMemberClass());
777 	}
778 
779 	@Test void isNonStaticMemberClass() {
780 		assertFalse(hPublic.isNonStaticMemberClass());
781 		assertTrue(hPublicMember.isNonStaticMemberClass());
782 		assertFalse(aClass.isNonStaticMemberClass());
783 		assertFalse(aInterface.isNonStaticMemberClass());
784 	}
785 
786 	@Test void isNonStaticMemberClass_onType() {
787 		assertTrue(aTypeInfo.isNonStaticMemberClass());
788 		assertFalse(pTypeInfo.isNonStaticMemberClass());
789 		assertFalse(pTypeDimensionalInfo.isNonStaticMemberClass());
790 		assertFalse(pTypeGenericInfo.isNonStaticMemberClass());
791 		assertFalse(pTypeGenericArgInfo.isNonStaticMemberClass());
792 	}
793 
794 	@Test void isLocalClass() {
795 		class F implements Function<Object,String>{
796 			@Override
797 			public String apply(Object t) {
798 				return null;
799 			}
800 		}
801 		assertFalse(aClass.isLocalClass());
802 		assertTrue(of(F.class).isLocalClass());
803 	}
804 
805 	@Test void isLocalClass_type() {
806 		assertFalse(aTypeInfo.isLocalClass());
807 		assertFalse(pTypeGenericArgInfo.isLocalClass());
808 	}
809 
810 	@Test void isNotLocalClass() {
811 		class F implements Function<Object,String>{
812 			@Override
813 			public String apply(Object t) {
814 				return null;
815 			}
816 		}
817 		assertTrue(aClass.isNotLocalClass());
818 		assertFalse(of(F.class).isNotLocalClass());
819 	}
820 
821 	@Test void isNotLocalClass_type() {
822 		assertTrue(aTypeInfo.isNotLocalClass());
823 		assertTrue(pTypeGenericArgInfo.isNotLocalClass());
824 	}
825 
826 	@Test void isVisible_public() {
827 		assertTrue(hPublic.isVisible(Visibility.PUBLIC));
828 		assertFalse(hProtected.isVisible(Visibility.PUBLIC));
829 		assertFalse(hPackage.isVisible(Visibility.PUBLIC));
830 		assertFalse(hPrivate.isVisible(Visibility.PUBLIC));
831 	}
832 
833 
834 	@Test void isVisible_protected() {
835 		assertTrue(hPublic.isVisible(Visibility.PROTECTED));
836 		assertTrue(hProtected.isVisible(Visibility.PROTECTED));
837 		assertFalse(hPackage.isVisible(Visibility.PROTECTED));
838 		assertFalse(hPrivate.isVisible(Visibility.PROTECTED));
839 	}
840 
841 	@Test void isVisible_package() {
842 		assertTrue(hPublic.isVisible(Visibility.DEFAULT));
843 		assertTrue(hProtected.isVisible(Visibility.DEFAULT));
844 		assertTrue(hPackage.isVisible(Visibility.DEFAULT));
845 		assertFalse(hPrivate.isVisible(Visibility.DEFAULT));
846 	}
847 
848 	@Test void isVisible_private() {
849 		assertTrue(hPublic.isVisible(Visibility.PRIVATE));
850 		assertTrue(hProtected.isVisible(Visibility.PRIVATE));
851 		assertTrue(hPackage.isVisible(Visibility.PRIVATE));
852 		assertTrue(hPrivate.isVisible(Visibility.PRIVATE));
853 	}
854 
855 	@Test void isVisible_onType() {
856 		assertTrue(aTypeInfo.isVisible(Visibility.PRIVATE));
857 		assertTrue(pTypeInfo.isVisible(Visibility.PRIVATE));
858 		assertTrue(pTypeDimensionalInfo.isVisible(Visibility.PRIVATE));
859 		assertTrue(pTypeGenericInfo.isVisible(Visibility.PRIVATE));
860 		assertFalse(pTypeGenericArgInfo.isVisible(Visibility.PRIVATE));
861 	}
862 
863 	@Test void isPrimitive() {
864 		assertTrue(of(int.class).isPrimitive());
865 		assertFalse(of(Integer.class).isPrimitive());
866 	}
867 
868 	@Test void isPrimitive_onType() {
869 		assertFalse(aTypeInfo.isPrimitive());
870 		assertFalse(pTypeGenericArgInfo.isPrimitive());
871 	}
872 
873 	@Test void isNotPrimitive() {
874 		assertFalse(of(int.class).isNotPrimitive());
875 		assertTrue(of(Integer.class).isNotPrimitive());
876 	}
877 
878 	@Test void isNotPrimitive_onType() {
879 		assertTrue(aTypeInfo.isNotPrimitive());
880 		assertTrue(pTypeInfo.isNotPrimitive());
881 		assertTrue(pTypeDimensionalInfo.isNotPrimitive());
882 		assertTrue(pTypeGenericInfo.isNotPrimitive());
883 		assertTrue(pTypeGenericArgInfo.isNotPrimitive());
884 	}
885 
886 	@Test void isInterface() {
887 		assertTrue(aInterface.isInterface());
888 		assertFalse(aClass.isInterface());
889 	}
890 
891 	@Test void isInterface_onType() {
892 		assertFalse(aTypeInfo.isInterface());
893 		assertFalse(pTypeGenericArgInfo.isInterface());
894 	}
895 
896 	@Test void isClass() {
897 		assertTrue(aClass.isClass());
898 		assertFalse(aInterface.isClass());
899 	}
900 
901 	@Test void isClass_onType() {
902 		assertTrue(aTypeInfo.isClass());
903 		assertFalse(pTypeInfo.isClass());
904 		assertFalse(pTypeDimensionalInfo.isClass());
905 		assertTrue(pTypeGenericInfo.isClass());
906 		assertFalse(pTypeGenericArgInfo.isClass());
907 	}
908 
909 	@Deprecated public abstract static class H2a {}
910 	private interface H2b {}
911 	@Deprecated class H2_Deprecated {}
912 	class H2_NotDeprecated {}
913 	public class H2_Public {}
914 	class H2_NotPublic {}
915 	public static class H2_Static {}
916 	class H2_NotStatic {}
917 	class H2_Member {}
918 	static class H2_StaticMember {}
919 	abstract class H2_Abstract {}
920 	class H2_NotAbstract {}
921 
922 	static ClassInfo h2a=of(H2a.class), h2b=of(H2b.class), h2Deprecated=of(H2_Deprecated.class), h2NotDeprecated=of(H2_NotDeprecated.class), h2Public=of(H2_Public.class), h2NotPublic=of(H2_NotPublic.class), h2Static=of(H2_Static.class), h2NotStatic=of(H2_NotStatic.class), h2Member=of(H2_Member.class), h2StaticMember=of(H2_StaticMember.class), h2Abstract=of(H2_Abstract.class), h2NotAbstract=of(H2_NotAbstract.class);  // NOSONAR
923 
924 	@Test void isAll() {
925 		assertTrue(h2a.isAll(DEPRECATED, PUBLIC, STATIC, MEMBER, ABSTRACT, ReflectFlags.CLASS));
926 		assertTrue(h2b.isAll(NOT_DEPRECATED, NOT_PUBLIC, STATIC, ABSTRACT, INTERFACE));
927 	}
928 
929 	@Test void isAll_onType() {
930 		assertTrue(aTypeInfo.isAll(PUBLIC, MEMBER, ReflectFlags.CLASS));
931 		assertFalse(pTypeInfo.isAll(PUBLIC, MEMBER, ReflectFlags.CLASS));
932 		assertFalse(pTypeDimensionalInfo.isAll(PUBLIC, MEMBER, ReflectFlags.CLASS));
933 		assertFalse(pTypeGenericInfo.isAll(PUBLIC, MEMBER, ReflectFlags.CLASS));
934 	}
935 
936 	@Test void isAll_deprecated() {
937 		assertTrue(h2Deprecated.isAll(DEPRECATED));
938 		assertFalse(h2NotDeprecated.isAll(DEPRECATED));
939 	}
940 
941 	@Test void isAll_notDeprecated() {
942 		assertFalse(h2Deprecated.isAll(NOT_DEPRECATED));
943 		assertTrue(h2NotDeprecated.isAll(NOT_DEPRECATED));
944 	}
945 
946 	@Test void isAll_public() {
947 		assertTrue(of(H2_Public.class).isAll(PUBLIC));
948 		assertFalse(h2NotPublic.isAll(PUBLIC));
949 	}
950 
951 	@Test void isAll_notPublic() {
952 		assertFalse(of(H2_Public.class).isAll(NOT_PUBLIC));
953 		assertTrue(h2NotPublic.isAll(NOT_PUBLIC));
954 	}
955 
956 	@Test void isAll_static() {
957 		assertTrue(of(H2_Static.class).isAll(STATIC));
958 		assertFalse(h2NotStatic.isAll(STATIC));
959 	}
960 
961 	@Test void isAll_notStatic() {
962 		assertFalse(of(H2_Static.class).isAll(NOT_STATIC));
963 		assertTrue(h2NotStatic.isAll(NOT_STATIC));
964 	}
965 
966 	@Test void isAll_member() {
967 		assertTrue(h2Member.isAll(MEMBER));
968 		assertTrue(h2StaticMember.isAll(MEMBER));
969 		assertFalse(aClass.isAll(MEMBER));
970 	}
971 
972 	@Test void isAll_notMember() {
973 		assertFalse(h2Member.isAll(NOT_MEMBER));
974 		assertFalse(h2StaticMember.isAll(NOT_MEMBER));
975 		assertTrue(aClass.isAll(NOT_MEMBER));
976 	}
977 
978 	@Test void isAll_abstract() {
979 		assertTrue(of(H2_Abstract.class).isAll(ABSTRACT));
980 		assertFalse(h2NotAbstract.isAll(ABSTRACT));
981 		assertTrue(aInterface.isAll(ABSTRACT));
982 	}
983 
984 	@Test void isAll_notAbstract() {
985 		assertFalse(of(H2_Abstract.class).isAll(NOT_ABSTRACT));
986 		assertTrue(h2NotAbstract.isAll(NOT_ABSTRACT));
987 		assertFalse(aInterface.isAll(NOT_ABSTRACT));
988 	}
989 
990 	@Test void isAll_interface() {
991 		assertTrue(aInterface.isAll(INTERFACE));
992 		assertFalse(aClass.isAll(INTERFACE));
993 	}
994 
995 	@Test void isAll_class() {
996 		assertFalse(aInterface.isAll(ReflectFlags.CLASS));
997 		assertTrue(aClass.isAll(ReflectFlags.CLASS));
998 	}
999 
1000 	@Test void isAll_invalid() {
1001 		var a = aClass;
1002 		assertThrows(Exception.class, ()->a.isAll(HAS_PARAMS));
1003 		assertThrows(Exception.class, ()->a.isAll(HAS_NO_PARAMS));
1004 		assertThrows(Exception.class, ()->a.isAll(TRANSIENT));
1005 		assertThrows(Exception.class, ()->a.isAll(NOT_TRANSIENT));
1006 	}
1007 
1008 	@Test void isAny() {
1009 		assertTrue(h2a.isAny(DEPRECATED));
1010 		assertTrue(h2a.isAny(PUBLIC));
1011 		assertTrue(h2a.isAny(STATIC));
1012 		assertTrue(h2a.isAny(MEMBER));
1013 		assertTrue(h2a.isAny(ABSTRACT));
1014 		assertTrue(h2a.isAny(ReflectFlags.CLASS));
1015 		assertTrue(h2b.isAny(NOT_DEPRECATED));
1016 		assertTrue(h2b.isAny(NOT_PUBLIC));
1017 		assertTrue(h2b.isAny(STATIC));
1018 		assertTrue(h2b.isAny(ABSTRACT));
1019 		assertTrue(h2b.isAny(INTERFACE));
1020 	}
1021 
1022 	@Test void isAny_onType() {
1023 		assertFalse(aTypeInfo.isAny(new ReflectFlags[0]));
1024 	}
1025 
1026 	@Test void isAny_deprecated() {
1027 		assertTrue(h2Deprecated.isAny(DEPRECATED));
1028 		assertFalse(h2NotDeprecated.isAny(DEPRECATED));
1029 	}
1030 
1031 	@Test void isAny_notDeprecated() {
1032 		assertFalse(h2Deprecated.isAny(NOT_DEPRECATED));
1033 		assertTrue(h2NotDeprecated.isAny(NOT_DEPRECATED));
1034 	}
1035 
1036 	@Test void isAny_public() {
1037 		assertTrue(h2Public.isAny(PUBLIC));
1038 		assertFalse(h2NotPublic.isAny(PUBLIC));
1039 	}
1040 
1041 	@Test void isAny_notPublic() {
1042 		assertFalse(h2Public.isAny(NOT_PUBLIC));
1043 		assertTrue(h2NotPublic.isAny(NOT_PUBLIC));
1044 	}
1045 
1046 	@Test void isAny_static() {
1047 		assertTrue(h2Static.isAny(STATIC));
1048 		assertFalse(h2NotStatic.isAny(STATIC));
1049 	}
1050 
1051 	@Test void isAny_notStatic() {
1052 		assertFalse(h2Static.isAny(NOT_STATIC));
1053 		assertTrue(h2NotStatic.isAny(NOT_STATIC));
1054 	}
1055 
1056 	@Test void isAny_member() {
1057 		assertTrue(h2Member.isAny(MEMBER));
1058 		assertTrue(h2StaticMember.isAny(MEMBER));
1059 		assertFalse(aClass.isAny(MEMBER));
1060 	}
1061 
1062 	@Test void isAny_notMember() {
1063 		assertFalse(h2Member.isAny(NOT_MEMBER));
1064 		assertFalse(h2StaticMember.isAny(NOT_MEMBER));
1065 		assertTrue(aClass.isAny(NOT_MEMBER));
1066 	}
1067 
1068 	@Test void isAny_abstract() {
1069 		assertTrue(h2Abstract.isAny(ABSTRACT));
1070 		assertFalse(h2NotAbstract.isAny(ABSTRACT));
1071 		assertTrue(aInterface.isAny(ABSTRACT));
1072 	}
1073 
1074 	@Test void isAny_notAbstract() {
1075 		assertFalse(h2Abstract.isAny(NOT_ABSTRACT));
1076 		assertTrue(h2NotAbstract.isAny(NOT_ABSTRACT));
1077 		assertFalse(aInterface.isAny(NOT_ABSTRACT));
1078 	}
1079 
1080 	@Test void isAny_interface() {
1081 		assertTrue(aInterface.isAny(INTERFACE));
1082 		assertFalse(aClass.isAny(INTERFACE));
1083 	}
1084 
1085 	@Test void isAny_class() {
1086 		assertFalse(aInterface.isAny(ReflectFlags.CLASS));
1087 		assertTrue(aClass.isAny(ReflectFlags.CLASS));
1088 	}
1089 
1090 	@Test void isAny_invalid() {
1091 		var a = aClass;
1092 		assertThrows(Exception.class, ()->a.isAny(HAS_PARAMS));
1093 		assertThrows(Exception.class, ()->a.isAny(HAS_NO_PARAMS));
1094 		assertThrows(Exception.class, ()->a.isAny(TRANSIENT));
1095 		assertThrows(Exception.class, ()->a.isAny(NOT_TRANSIENT));
1096 	}
1097 
1098 	//-----------------------------------------------------------------------------------------------------------------
1099 	// Primitive wrappers
1100 	//-----------------------------------------------------------------------------------------------------------------
1101 
1102 	static List<Class<?>> primitives = list(boolean.class,byte.class,short.class,char.class,int.class,long.class,float.class,double.class);
1103 	static List<Class<?>> primitiveWrappers = list(Boolean.class,Byte.class,Short.class,Character.class,Integer.class,Long.class,Float.class,Double.class);
1104 	static List<Object> primitiveDefaults = list(false,(byte)0,(short)0,(char)0,0,0L,0f,0d);
1105 
1106 	@Test void hasPrimitiveWrapper() {
1107 		for (Class<?> c : primitives)
1108 			assertTrue(of(c).hasPrimitiveWrapper());
1109 		for (Class<?> c : primitiveWrappers)
1110 			assertFalse(of(c).hasPrimitiveWrapper());
1111 	}
1112 
1113 	@Test void hasPrimitiveWrapper_onType() {
1114 		assertFalse(aTypeInfo.hasPrimitiveWrapper());
1115 	}
1116 
1117 	@Test void getPrimitiveWrapper() {
1118 		for (int i = 0; i < primitives.size(); i++)
1119 			assertEquals(of(primitives.get(i)).getPrimitiveWrapper(), primitiveWrappers.get(i));
1120 		assertNull(of(String.class).getPrimitiveWrapper());
1121 	}
1122 
1123 	@Test void getPrimitiveWrapper_onType() {
1124 		assertNull(aTypeInfo.getPrimitiveWrapper());
1125 	}
1126 
1127 	@Test void getPrimitiveForWrapper() {
1128 		for (int i = 0; i < primitives.size(); i++)
1129 			assertEquals(of(primitiveWrappers.get(i)).getPrimitiveForWrapper(), primitives.get(i));
1130 		assertNull(of(String.class).getPrimitiveForWrapper());
1131 	}
1132 
1133 	@Test void getPrimitiveForWrapper_onType() {
1134 		assertNull(aTypeInfo.getPrimitiveForWrapper());
1135 	}
1136 
1137 	@Test void getWrapperIfPrimitive() {
1138 		for (int i = 0; i < primitives.size(); i++)
1139 			assertEquals(of(primitives.get(i)).getWrapperIfPrimitive(), primitiveWrappers.get(i));
1140 		assertEquals(of(String.class).getWrapperIfPrimitive(), String.class);
1141 	}
1142 
1143 	@Test void getWrapperIfPrimitive_onType() {
1144 		assertEquals("class org.apache.juneau.reflect.ClassInfo_Test$A1", aTypeInfo.getWrapperIfPrimitive().toString());
1145 		assertEquals("interface java.util.Map", pTypeInfo.getWrapperIfPrimitive().toString());
1146 		assertEquals("interface java.util.Map", pTypeDimensionalInfo.getWrapperIfPrimitive().toString());
1147 		assertEquals("class java.util.AbstractMap", pTypeGenericInfo.getWrapperIfPrimitive().toString());
1148 		assertEquals(null, pTypeGenericArgInfo.getWrapperIfPrimitive());
1149 	}
1150 
1151 	@Test void getWrapperInfoIfPrimitive() {
1152 		for (int i = 0; i < primitives.size(); i++)
1153 			assertEquals(of(primitives.get(i)).getWrapperInfoIfPrimitive().inner(), primitiveWrappers.get(i));
1154 		assertEquals(of(String.class).getWrapperInfoIfPrimitive().inner(), String.class);
1155 	}
1156 
1157 	@Test void getWrapperInfoIfPrimitive_onType() {
1158 		assertEquals(aTypeInfo.getWrapperInfoIfPrimitive().innerType(), aType);
1159 		check("V", pTypeGenericArgInfo.getWrapperInfoIfPrimitive());
1160 	}
1161 
1162 	@Test void getPrimitiveDefault() {
1163 		for (int i = 0; i < primitives.size(); i++)
1164 			assertEquals(of(primitives.get(i)).getPrimitiveDefault(), primitiveDefaults.get(i));
1165 		assertNull(of(String.class).getPrimitiveDefault());
1166 	}
1167 
1168 	@Test void getPrimitiveDefault_onType() {
1169 		assertNull(aTypeInfo.getPrimitiveDefault());
1170 	}
1171 
1172 	//-----------------------------------------------------------------------------------------------------------------
1173 	// Labels
1174 	//-----------------------------------------------------------------------------------------------------------------
1175 
1176 	public class J1 {}
1177 	public static class J2 {}
1178 
1179 	static ClassInfo j1=of(J1.class), j2=of(J2.class), j1_3d=of(J1[][].class), j2_3d=of(J2[][].class);
1180 
1181 	@Test void getFullName_simple() {
1182 		assertEquals("org.apache.juneau.reflect.AClass", aClass.getFullName());
1183 	}
1184 
1185 	@Test void getFullName_simpleTwice() {
1186 		assertEquals("org.apache.juneau.reflect.AClass", aClass.getFullName());
1187 		assertEquals("org.apache.juneau.reflect.AClass", aClass.getFullName());
1188 	}
1189 
1190 	@Test void getFullName_simpleArray() {
1191 		assertEquals("org.apache.juneau.reflect.AClass[][]", of(AClass[][].class).getFullName());
1192 	}
1193 
1194 	@Test void getFullName_inner() {
1195 		assertEquals("org.apache.juneau.reflect.ClassInfo_Test$J1", j1.getFullName());
1196 		assertEquals("org.apache.juneau.reflect.ClassInfo_Test$J2", j2.getFullName());
1197 	}
1198 
1199 	@Test void getFullName_innerArray() {
1200 		assertEquals("org.apache.juneau.reflect.ClassInfo_Test$J1[][]", j1_3d.getFullName());
1201 		assertEquals("org.apache.juneau.reflect.ClassInfo_Test$J2[][]", j2_3d.getFullName());
1202 	}
1203 
1204 	@Test void getFullName_primitive() {
1205 		assertEquals("int", of(int.class).getFullName());
1206 	}
1207 
1208 	@Test void getFullName_primitiveArray() {
1209 		assertEquals("int[][]", of(int[][].class).getFullName());
1210 	}
1211 
1212 	@Test void getFullName_simpleType() {
1213 		assertEquals("org.apache.juneau.reflect.ClassInfo_Test$A1", aTypeInfo.getFullName());
1214 	}
1215 
1216 	@Test void getFullName_complexType() {
1217 		assertEquals("java.util.Map<java.lang.String,java.util.List<java.lang.String>>", pTypeInfo.getFullName());
1218 	}
1219 
1220 	@Test void getFullName_dimensionalType() {
1221 		assertEquals("java.util.Map<java.lang.String,java.lang.String[][]>", pTypeDimensionalInfo.getFullName());
1222 	}
1223 
1224 	@Test void getFullName_genericType() {
1225 		assertEquals("java.util.AbstractMap<K,V>", pTypeGenericInfo.getFullName());
1226 	}
1227 
1228 	@Test void getFullName_genericTypeArg() {
1229 		assertEquals("V", pTypeGenericArgInfo.getFullName());
1230 	}
1231 
1232 	@Test void getFullName_localClass() {
1233 		@SuppressWarnings("serial")
1234 		class LocalClass implements Serializable {}
1235 		assertEquals("org.apache.juneau.reflect.ClassInfo_Test$1LocalClass", of(LocalClass.class).getFullName());
1236 	}
1237 
1238 	@Test void getShortName_simple() {
1239 		assertEquals("AClass", aClass.getShortName());
1240 	}
1241 
1242 	@Test void getShortName_simpleTwice() {
1243 		assertEquals("AClass", aClass.getShortName());
1244 		assertEquals("AClass", aClass.getShortName());
1245 	}
1246 
1247 	@Test void getShortName_simpleArray() {
1248 		assertEquals("AClass[][]", of(AClass[][].class).getShortName());
1249 	}
1250 
1251 	@Test void getShortName_inner() {
1252 		assertEquals("ClassInfo_Test$J1", j1.getShortName());
1253 		assertEquals("ClassInfo_Test$J2", j2.getShortName());
1254 	}
1255 
1256 	@Test void getShortName_innerArray() {
1257 		assertEquals("ClassInfo_Test$J1[][]", j1_3d.getShortName());
1258 		assertEquals("ClassInfo_Test$J2[][]", j2_3d.getShortName());
1259 	}
1260 
1261 	@Test void getShortName_primitive() {
1262 		assertEquals("int", of(int.class).getShortName());
1263 	}
1264 
1265 	@Test void getShortName_primitiveArray() {
1266 		assertEquals("int[][]", of(int[][].class).getShortName());
1267 	}
1268 
1269 	@Test void getShortName_simpleType() {
1270 		assertEquals("ClassInfo_Test$A1", aTypeInfo.getShortName());
1271 	}
1272 
1273 	@Test void getShortName_complexType() {
1274 		assertEquals("Map<String,List<String>>", pTypeInfo.getShortName());
1275 	}
1276 
1277 	@Test void getShortName_dimensionalType() {
1278 		assertEquals("Map<String,String[][]>", pTypeDimensionalInfo.getShortName());
1279 	}
1280 
1281 	@Test void getShortName_genericType() {
1282 		assertEquals("AbstractMap<K,V>", pTypeGenericInfo.getShortName());
1283 	}
1284 
1285 	@Test void getShortName_genericTypeArg() {
1286 		assertEquals("V", pTypeGenericArgInfo.getShortName());
1287 	}
1288 
1289 	@Test void getShortName_localClass() {
1290 		@SuppressWarnings("serial")
1291 		class LocalClass implements Serializable {}
1292 		assertEquals("ClassInfo_Test$LocalClass", of(LocalClass.class).getShortName());
1293 	}
1294 
1295 
1296 	@Test void getSimpleName_simple() {
1297 		assertEquals("AClass", aClass.getSimpleName());
1298 	}
1299 
1300 	@Test void getSimpleName_simpleTwice() {
1301 		assertEquals("AClass", aClass.getSimpleName());
1302 		assertEquals("AClass", aClass.getSimpleName());
1303 	}
1304 
1305 	@Test void getSimpleName_simpleArray() {
1306 		assertEquals("AClass[][]", of(AClass[][].class).getSimpleName());
1307 	}
1308 
1309 	@Test void getSimpleName_inner() {
1310 		assertEquals("J1", j1.getSimpleName());
1311 		assertEquals("J2", j2.getSimpleName());
1312 	}
1313 
1314 	@Test void getSimpleName_innerArray() {
1315 		assertEquals("J1[][]", j1_3d.getSimpleName());
1316 		assertEquals("J2[][]", j2_3d.getSimpleName());
1317 	}
1318 
1319 	@Test void getSimpleName_primitive() {
1320 		assertEquals("int", of(int.class).getSimpleName());
1321 	}
1322 
1323 	@Test void getSimpleName_primitiveArray() {
1324 		assertEquals("int[][]", of(int[][].class).getSimpleName());
1325 	}
1326 
1327 	@Test void getSimpleName_simpleType() {
1328 		assertEquals("A1", aTypeInfo.getSimpleName());
1329 	}
1330 
1331 	@Test void getSimpleName_complexType() {
1332 		assertEquals("Map", pTypeInfo.getSimpleName());
1333 	}
1334 
1335 	@Test void getSimpleName_dimensionalType() {
1336 		assertEquals("Map", pTypeDimensionalInfo.getSimpleName());
1337 	}
1338 
1339 	@Test void getSimpleName_genericType() {
1340 		assertEquals("AbstractMap", pTypeGenericInfo.getSimpleName());
1341 	}
1342 
1343 	@Test void getSimpleName_genericTypeArg() {
1344 		assertEquals("V", pTypeGenericArgInfo.getSimpleName());
1345 	}
1346 
1347 	@Test void getSimpleName_localClass() {
1348 		@SuppressWarnings("serial")
1349 		class LocalClass implements Serializable {}
1350 		assertEquals("LocalClass", of(LocalClass.class).getSimpleName());
1351 	}
1352 
1353 	@Test void getName() {
1354 		assertEquals("org.apache.juneau.reflect.AClass", aClass.getName());
1355 		assertEquals("java.util.AbstractMap", pTypeGenericInfo.getName());
1356 		assertEquals("V", pTypeGenericArgInfo.getName());
1357 	}
1358 
1359 	//-----------------------------------------------------------------------------------------------------------------
1360 	// Hierarchy
1361 	//-----------------------------------------------------------------------------------------------------------------
1362 
1363 	public interface KA {}
1364 	public static class KB implements KA {}
1365 	public static class KC extends KB {}
1366 
1367 	static ClassInfo ka=of(KA.class), kb=of(KB.class), kc=of(KC.class);
1368 
1369 
1370 	@Test void isParentOf() {
1371 		assertTrue(ka.isParentOf(KA.class));
1372 		assertTrue(ka.isParentOf(KB.class));
1373 		assertTrue(ka.isParentOf(KC.class));
1374 		assertFalse(kb.isParentOf(KA.class));
1375 		assertTrue(kb.isParentOf(KB.class));
1376 		assertTrue(kb.isParentOf(KC.class));
1377 		assertFalse(kc.isParentOf(KA.class));
1378 		assertFalse(kc.isParentOf(KB.class));
1379 		assertTrue(kc.isParentOf(KC.class));
1380 	}
1381 
1382 	@Test void isParentOf_null() {
1383 		assertFalse(ka.isParentOf(null));
1384 	}
1385 
1386 	@Test void isParentOf_type() {
1387 		assertFalse(ka.isParentOf(aType));
1388 		assertFalse(ka.isParentOf(pType));
1389 		assertFalse(ka.isParentOf(pTypeDimensional));
1390 		assertFalse(ka.isParentOf(pTypeGeneric));
1391 		assertFalse(ka.isParentOf(pTypeGenericArg));
1392 
1393 		assertFalse(aTypeInfo.isParentOf(KA.class));
1394 		assertFalse(pTypeInfo.isParentOf(KA.class));
1395 		assertFalse(pTypeDimensionalInfo.isParentOf(KA.class));
1396 		assertFalse(pTypeGenericInfo.isParentOf(KA.class));
1397 		assertFalse(pTypeGenericArgInfo.isParentOf(KA.class));
1398 	}
1399 
1400 	@Test void isChildOf() {
1401 		assertTrue(ka.isChildOf(KA.class));
1402 		assertFalse(ka.isChildOf(KB.class));
1403 		assertFalse(ka.isChildOf(KC.class));
1404 		assertTrue(kb.isChildOf(KA.class));
1405 		assertTrue(kb.isChildOf(KB.class));
1406 		assertFalse(kb.isChildOf(KC.class));
1407 		assertTrue(kc.isChildOf(KA.class));
1408 		assertTrue(kc.isChildOf(KB.class));
1409 		assertTrue(kc.isChildOf(KC.class));
1410 	}
1411 
1412 	@Test void isChildOf_null() {
1413 		assertFalse(ka.isChildOf((Class<?>)null));
1414 	}
1415 
1416 	@Test void isChildOf_type() {
1417 		assertFalse(ka.isChildOf(aType));
1418 		assertFalse(ka.isChildOf(pType));
1419 		assertFalse(ka.isChildOf(pTypeDimensional));
1420 		assertFalse(ka.isChildOf(pTypeGeneric));
1421 		assertFalse(ka.isChildOf(pTypeGenericArg));
1422 
1423 		assertFalse(aTypeInfo.isChildOf(KA.class));
1424 		assertFalse(pTypeInfo.isChildOf(KA.class));
1425 		assertFalse(pTypeDimensionalInfo.isChildOf(KA.class));
1426 		assertFalse(pTypeGenericInfo.isChildOf(KA.class));
1427 		assertFalse(pTypeGenericArgInfo.isChildOf(KA.class));
1428 	}
1429 
1430 	@Test void isStrictChildOf() {
1431 		assertFalse(ka.isStrictChildOf(KA.class));
1432 		assertFalse(ka.isStrictChildOf(KB.class));
1433 		assertFalse(ka.isStrictChildOf(KC.class));
1434 		assertTrue(kb.isStrictChildOf(KA.class));
1435 		assertFalse(kb.isStrictChildOf(KB.class));
1436 		assertFalse(kb.isStrictChildOf(KC.class));
1437 		assertTrue(kc.isStrictChildOf(KA.class));
1438 		assertTrue(kc.isStrictChildOf(KB.class));
1439 		assertFalse(kc.isStrictChildOf(KC.class));
1440 	}
1441 
1442 	@Test void isStrictChildOf_null() {
1443 		assertFalse(ka.isStrictChildOf(null));
1444 	}
1445 
1446 	@Test void isStrictChildOf_type() {
1447 		assertFalse(aTypeInfo.isStrictChildOf(KA.class));
1448 		assertFalse(pTypeInfo.isStrictChildOf(KA.class));
1449 		assertFalse(pTypeDimensionalInfo.isStrictChildOf(KA.class));
1450 		assertFalse(pTypeGenericInfo.isStrictChildOf(KA.class));
1451 		assertFalse(pTypeGenericArgInfo.isStrictChildOf(KA.class));
1452 	}
1453 
1454 	@Test void isChildOfAny() {
1455 		assertTrue(ka.isChildOfAny(KA.class));
1456 		assertFalse(ka.isChildOfAny(KB.class));
1457 		assertFalse(ka.isChildOfAny(KC.class));
1458 		assertTrue(kb.isChildOfAny(KA.class));
1459 		assertTrue(kb.isChildOfAny(KB.class));
1460 		assertFalse(kb.isChildOfAny(KC.class));
1461 		assertTrue(kc.isChildOfAny(KA.class));
1462 		assertTrue(kc.isChildOfAny(KB.class));
1463 		assertTrue(kc.isChildOfAny(KC.class));
1464 	}
1465 
1466 	@Test void isChildOfAny_type() {
1467 		assertFalse(aTypeInfo.isChildOfAny(KA.class));
1468 		assertFalse(pTypeInfo.isChildOfAny(KA.class));
1469 		assertFalse(pTypeDimensionalInfo.isChildOfAny(KA.class));
1470 		assertFalse(pTypeGenericInfo.isChildOfAny(KA.class));
1471 		assertFalse(pTypeGenericArgInfo.isChildOfAny(KA.class));
1472 	}
1473 
1474 	@Test void is() {
1475 		assertTrue(ka.is(KA.class));
1476 		assertFalse(ka.is(KB.class));
1477 		assertFalse(ka.is(KC.class));
1478 		assertFalse(kb.is(KA.class));
1479 		assertTrue(kb.is(KB.class));
1480 		assertFalse(kb.is(KC.class));
1481 		assertFalse(kc.is(KA.class));
1482 		assertFalse(kc.is(KB.class));
1483 		assertTrue(kc.is(KC.class));
1484 	}
1485 
1486 	@Test void is_ClassInfo() {
1487 		assertTrue(ka.is(of(KA.class)));
1488 		assertFalse(ka.is(of(KB.class)));
1489 		assertFalse(ka.is(of(KC.class)));
1490 		assertFalse(kb.is(of(KA.class)));
1491 		assertTrue(kb.is(of(KB.class)));
1492 		assertFalse(kb.is(of(KC.class)));
1493 		assertFalse(kc.is(of(KA.class)));
1494 		assertFalse(kc.is(of(KB.class)));
1495 		assertTrue(kc.is(of(KC.class)));
1496 	}
1497 
1498 	@Test void is_ClassInfo_genType() {
1499 		assertFalse(pTypeGenericArgInfo.is(of(KA.class)));
1500 	}
1501 
1502 	@Test void isAnyType() {
1503 		assertTrue(ka.isAny(KA.class));
1504 		assertTrue(ka.isAny(KA.class, KB.class));
1505 		assertFalse(ka.isAny(KB.class));
1506 		assertFalse(ka.isAny(KC.class));
1507 		assertFalse(kb.isAny(KA.class));
1508 		assertTrue(kb.isAny(KB.class));
1509 		assertFalse(kb.isAny(KC.class));
1510 		assertFalse(kc.isAny(KA.class));
1511 		assertFalse(kc.isAny(KB.class));
1512 		assertTrue(kc.isAny(KC.class));
1513 	}
1514 
1515 
1516 	@Test void is_type() {
1517 		assertFalse(aTypeInfo.is(KA.class));
1518 		assertFalse(pTypeInfo.is(KA.class));
1519 		assertFalse(pTypeDimensionalInfo.is(KA.class));
1520 		assertFalse(pTypeGenericInfo.is(KA.class));
1521 		assertFalse(pTypeGenericArgInfo.is(KA.class));
1522 	}
1523 
1524 	@Test void getPackage() {
1525 		check("org.apache.juneau.reflect", ka.getPackage().getName());
1526 	}
1527 
1528 	@Test void getPackage_type() {
1529 		check("org.apache.juneau.reflect", aTypeInfo.getPackage());
1530 		check("java.util", pTypeInfo.getPackage());
1531 		check("java.util", pTypeDimensionalInfo.getPackage());
1532 		check("java.util", pTypeGenericInfo.getPackage());
1533 		check(null, pTypeGenericArgInfo.getPackage());
1534 	}
1535 
1536 	@Test void hasPackage() {
1537 		assertTrue(ka.hasPackage());
1538 	}
1539 
1540 	@Test void hasPackage_type() {
1541 		assertTrue(aTypeInfo.hasPackage());
1542 		assertTrue(pTypeInfo.hasPackage());
1543 		assertTrue(pTypeDimensionalInfo.hasPackage());
1544 		assertTrue(pTypeGenericInfo.hasPackage());
1545 		assertFalse(pTypeGenericArgInfo.hasPackage());
1546 	}
1547 
1548 	@Test void getDimensions() {
1549 		assertEquals(0, ka.getDimensions());
1550 		assertEquals(2, of(KA[][].class).getDimensions());
1551 	}
1552 
1553 	@Test void getDimensions_type() {
1554 		assertEquals(0, aTypeInfo.getDimensions());
1555 		assertEquals(0, pTypeInfo.getDimensions());
1556 		assertEquals(0, pTypeDimensionalInfo.getDimensions());
1557 		assertEquals(0, pTypeGenericInfo.getDimensions());
1558 		assertEquals(0, pTypeGenericArgInfo.getDimensions());
1559 	}
1560 
1561 	@Test void getComponentType() {
1562 		check("KA", ka.getComponentType());
1563 		check("KA", of(KA[][].class).getComponentType());
1564 	}
1565 
1566 	@Test void getComponentType_twice() {
1567 		check("KA", ka.getComponentType());
1568 		check("KA", ka.getComponentType());
1569 	}
1570 
1571 	@Test void getComponentType_type() {
1572 		check("A1", aTypeInfo.getComponentType());
1573 		check("Map", pTypeInfo.getComponentType());
1574 		check("Map", pTypeDimensionalInfo.getComponentType());
1575 		check("AbstractMap", pTypeGenericInfo.getComponentType());
1576 		check("V", pTypeGenericArgInfo.getComponentType());
1577 	}
1578 
1579 	//-----------------------------------------------------------------------------------------------------------------
1580 	// Instantiation
1581 	//-----------------------------------------------------------------------------------------------------------------
1582 
1583 	public static class LA {}
1584 
1585 	static ClassInfo la=of(LA.class);
1586 
1587 	@Test void newInstance() {
1588 		assertNotNull(la.newInstance());
1589 	}
1590 
1591 	@Test void newInstance_type() {
1592 		assertThrows(ExecutableException.class, ()->aTypeInfo.newInstance());
1593 		assertThrows(ExecutableException.class, ()->pTypeInfo.newInstance());
1594 		assertThrows(ExecutableException.class, ()->pTypeDimensionalInfo.newInstance());
1595 		assertThrows(Exception.class, ()->pTypeGenericInfo.newInstance());
1596 		assertThrows(ExecutableException.class, ()->pTypeGenericArgInfo.newInstance());
1597 	}
1598 
1599 	//-----------------------------------------------------------------------------------------------------------------
1600 	// Parameter types
1601 	//-----------------------------------------------------------------------------------------------------------------
1602 
1603 	@SuppressWarnings("serial")
1604 	public static class MA extends HashMap<String,Integer> {}
1605 	@SuppressWarnings("serial")
1606 	public static class MB extends MA {}
1607 	@SuppressWarnings("serial")
1608 	public static class MC<K,E> extends HashMap<K,E> {}
1609 	@SuppressWarnings("serial")
1610 	public static class MD extends MC<String,Integer> {}
1611 	@SuppressWarnings("serial")
1612 	public static class ME extends HashMap<String,HashMap<String,Integer>> {}
1613 	@SuppressWarnings("serial")
1614 	public static class MF extends HashMap<String,String[]> {}
1615 	@SuppressWarnings("serial")
1616 	public static class MG extends HashMap<String,HashMap<String,Integer>[]> {}
1617 	@SuppressWarnings({ "serial", "rawtypes" })
1618 	public static class MH extends HashMap<String,LinkedList[]> {}
1619 	@SuppressWarnings({ "serial"})
1620 	public static class MI<X> extends HashMap<String,X[]> {}
1621 	@SuppressWarnings({ "serial"})
1622 	public static class MJ<X extends Number> extends HashMap<String,X> {}
1623 	public class MK {}
1624 	@SuppressWarnings({ "serial"})
1625 	public class ML extends HashMap<String,MK> {}
1626 	public static class MM {
1627 		@SuppressWarnings({ "serial"})
1628 		public class MN extends HashMap<String,MM> {}
1629 	}
1630 
1631 
1632 	static ClassInfo ma=of(MA.class), mb=of(MB.class), mc=of(MC.class), md=of(MD.class), me=of(ME.class), mf=of(MF.class), mg=of(MG.class), mh=of(MH.class), mi=of(MI.class), mj=of(MJ.class), ml=of(ML.class), mn=of(MM.MN.class);
1633 
1634 	@Test void getParameterType_simpleMap() {
1635 		check("String", ma.getParameterType(0, HashMap.class));
1636 		check("Integer", ma.getParameterType(1, HashMap.class));
1637 		check("String", mb.getParameterType(0, HashMap.class));
1638 		check("Integer", mb.getParameterType(1, HashMap.class));
1639 	}
1640 
1641 	@Test void getParameterType_outOfBounds() {
1642 		assertThrowsWithMessage(IllegalArgumentException.class, "Invalid type index. index=2, argsLength=2", ()->ma.getParameterType(2, HashMap.class));
1643 	}
1644 
1645 	@Test void getParameterType_notASubclass() {
1646 		assertThrowsWithMessage(IllegalArgumentException.class, "Class 'AClass' is not a subclass of parameterized type 'HashMap'", ()->aClass.getParameterType(2, HashMap.class));
1647 	}
1648 
1649 	@Test void getParameterType_nullParameterizedType() {
1650 		assertThrowsWithMessage(IllegalArgumentException.class, "Argument 'pt' cannot be null.", ()->aClass.getParameterType(2, null));
1651 	}
1652 
1653 	@Test void getParameterType_notParamerizedType() {
1654 		assertThrowsWithMessage(IllegalArgumentException.class, "Class 'MA' is not a parameterized type", ()->mb.getParameterType(2, MA.class));
1655 	}
1656 
1657 	@Test void getParameterType_unresolvedTypes() {
1658 		assertThrowsWithMessage(IllegalArgumentException.class, "Could not resolve variable 'E' to a type.", ()->mc.getParameterType(1, HashMap.class));
1659 	}
1660 
1661 	@Test void getParameterType_resolvedTypes() {
1662 		check("Integer", md.getParameterType(1, HashMap.class));
1663 	}
1664 
1665 	@Test void getParameterType_parameterizedTypeVariable() {
1666 		check("HashMap", me.getParameterType(1, HashMap.class));
1667 	}
1668 
1669 	@Test void getParameterType_arrayParameterType() {
1670 		check("String[]", mf.getParameterType(1, HashMap.class));
1671 	}
1672 
1673 	@Test void getParameterType_genericArrayTypeParameter() {
1674 		check("HashMap[]", mg.getParameterType(1, HashMap.class));
1675 	}
1676 
1677 	@Test void getParameterType_genericArrayTypeParameterWithoutTypes() {
1678 		check("LinkedList[]", mh.getParameterType(1, HashMap.class));
1679 	}
1680 
1681 	@Test void getParameterType_unresolvedGenericArrayType() {
1682 		assertThrowsWithMessage(IllegalArgumentException.class, "Could not resolve variable 'X[]' to a type.", ()->mi.getParameterType(1, HashMap.class));
1683 	}
1684 
1685 	@Test void getParameterType_wildcardType() {
1686 		assertThrowsWithMessage(IllegalArgumentException.class, "Could not resolve variable 'X' to a type.", ()->mj.getParameterType(1, HashMap.class));
1687 	}
1688 
1689 	@Test void getParameterType_innerType() {
1690 		check("MK", ml.getParameterType(1, HashMap.class));
1691 	}
1692 
1693 	@Test void getParameterType_nestedType() {
1694 		check("MM", mn.getParameterType(1, HashMap.class));
1695 	}
1696 
1697 	//-----------------------------------------------------------------------------------------------------------------
1698 	// ClassInfo.isParentOfFuzzyPrimitives(Class)
1699 	// ClassInfo.isParentOfFuzzyPrimitives(Type)
1700 	//-----------------------------------------------------------------------------------------------------------------
1701 
1702 	@Test void o01_isParentOfFuzzyPrimitives() {
1703 		assertTrue(ClassInfo.of(String.class).isParentOfFuzzyPrimitives(String.class));
1704 		assertTrue(ClassInfo.of(CharSequence.class).isParentOfFuzzyPrimitives(String.class));
1705 		assertFalse(ClassInfo.of(String.class).isParentOfFuzzyPrimitives(CharSequence.class));
1706 		assertTrue(ClassInfo.of(int.class).isParentOfFuzzyPrimitives(Integer.class));
1707 		assertTrue(ClassInfo.of(Integer.class).isParentOfFuzzyPrimitives(int.class));
1708 		assertTrue(ClassInfo.of(Number.class).isParentOfFuzzyPrimitives(int.class));
1709 		assertFalse(ClassInfo.of(int.class).isParentOfFuzzyPrimitives(Number.class));
1710 		assertFalse(ClassInfo.of(int.class).isParentOfFuzzyPrimitives(long.class));
1711 	}
1712 
1713 	//-----------------------------------------------------------------------------------------------------------------
1714 	// Other
1715 	//-----------------------------------------------------------------------------------------------------------------
1716 
1717 	@Test void xToString() {
1718 		assertEquals("class org.apache.juneau.reflect.AClass", aClass.toString());
1719 		assertEquals("interface org.apache.juneau.reflect.AInterface", aInterface.toString());
1720 		assertEquals("class org.apache.juneau.reflect.ClassInfo_Test$A1", aType.toString());
1721 		assertEquals("java.util.Map<java.lang.String, java.util.List<java.lang.String>>", pType.toString());
1722 		assertEquals("java.util.Map<java.lang.String, java.lang.String[][]>", pTypeDimensional.toString());
1723 		assertEquals("java.util.AbstractMap<K, V>", pTypeGeneric.toString());
1724 		assertEquals("V", pTypeGenericArg.toString());
1725 	}
1726 }