1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.reflect;
18
19 import static com.google.common.truth.Truth.assertThat;
20
21 import com.google.common.base.Function;
22 import com.google.common.collect.ImmutableList;
23 import com.google.common.collect.ImmutableMap;
24 import com.google.common.collect.ImmutableSet;
25 import com.google.common.collect.Maps;
26 import com.google.common.primitives.Primitives;
27 import com.google.common.testing.EqualsTester;
28 import com.google.common.testing.NullPointerTester;
29 import com.google.common.testing.SerializableTester;
30 import com.google.common.truth.CollectionSubject;
31
32 import junit.framework.TestCase;
33
34 import java.io.Serializable;
35 import java.lang.reflect.Constructor;
36 import java.lang.reflect.GenericArrayType;
37 import java.lang.reflect.Method;
38 import java.lang.reflect.ParameterizedType;
39 import java.lang.reflect.Type;
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.List;
44 import java.util.Map;
45
46
47
48
49
50
51
52 public class TypeTokenTest extends TestCase {
53
54 private abstract static class StringList implements List<String> {}
55
56 private abstract static class IntegerList implements List<Integer> {}
57
58 public void testValueEqualityNotInstanceEquality() {
59 TypeToken<List<String>> a = new TypeToken<List<String>>() {};
60 TypeToken<List<String>> b = new TypeToken<List<String>>() {};
61 assertEquals(a, b);
62 }
63
64 public <T> void testVariableTypeTokenNotAllowed() {
65 try {
66 new TypeToken<T>() {};
67 fail();
68 } catch (IllegalStateException expected) {}
69 }
70
71 public void testRawTypeIsCorrect() {
72 TypeToken<List<String>> token = new TypeToken<List<String>>() {};
73 assertEquals(List.class, token.getRawType());
74 }
75
76 public void testTypeIsCorrect() {
77 TypeToken<List<String>> token = new TypeToken<List<String>>() {};
78 assertEquals(StringList.class.getGenericInterfaces()[0], token.getType());
79 }
80
81 @SuppressWarnings("rawtypes")
82 public void testGetClass() {
83 TypeToken<List> token = TypeToken.of(List.class);
84 assertEquals(new TypeToken<List>() {}, token);
85 }
86
87 public void testGetType() {
88 TypeToken<?> t = TypeToken.of(StringList.class.getGenericInterfaces()[0]);
89 assertEquals(new TypeToken<List<String>>() {}, t);
90 }
91
92 public void testNonStaticLocalClass() {
93 class Local<T> {}
94 TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
95 assertEquals(Types.newParameterizedType(Local.class, String.class),
96 type.getType());
97 assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
98 }
99
100 public void testStaticLocalClass() {
101 doTestStaticLocalClass();
102 }
103
104 private static void doTestStaticLocalClass() {
105 class Local<T> {}
106 TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
107 assertEquals(Types.newParameterizedType(Local.class, String.class),
108 type.getType());
109 assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
110 }
111
112 public void testGenericArrayType() throws Exception {
113 TypeToken<List<String>[]> token = new TypeToken<List<String>[]>() {};
114 assertEquals(List[].class, token.getRawType());
115 assertTrue(token.getType() instanceof GenericArrayType);
116 }
117
118 public void testMultiDimensionalGenericArrayType() throws Exception {
119 TypeToken<List<Long>[][][]> token = new TypeToken<List<Long>[][][]>() {};
120 assertEquals(List[][][].class, token.getRawType());
121 assertTrue(token.getType() instanceof GenericArrayType);
122 }
123
124 public <T> void testGenericVariableTypeArrays() throws Exception {
125 assertEquals("T[]", new TypeToken<T[]>() {}.toString());
126 }
127
128 public void testResolveType() throws Exception {
129 Method getFromList = List.class.getMethod("get", int.class);
130 TypeToken<?> returnType = new TypeToken<List<String>>() {}
131 .resolveType(getFromList.getGenericReturnType());
132 assertEquals(String.class, returnType.getType());
133 }
134
135 public <F extends Enum<F> & Function<String, Integer> & Iterable<Long>>
136 void testResolveType_fromTypeVariable() throws Exception {
137 TypeToken<?> f = TypeToken.of(new TypeCapture<F>() {}.capture());
138 assertEquals(String.class,
139 f.resolveType(Function.class.getTypeParameters()[0]).getType());
140 assertEquals(Integer.class,
141 f.resolveType(Function.class.getTypeParameters()[1]).getType());
142 assertEquals(Long.class,
143 f.resolveType(Iterable.class.getTypeParameters()[0]).getType());
144 }
145
146 public <E extends Comparable<Iterable<String>> & Iterable<Integer>>
147 void testResolveType_fromTypeVariable_onlyDirectBoundsAreUsed() throws Exception {
148 TypeToken<?> e = TypeToken.of(new TypeCapture<E>() {}.capture());
149 assertEquals(Integer.class,
150 e.resolveType(Iterable.class.getTypeParameters()[0]).getType());
151 }
152
153 public void testResolveType_fromWildcard() throws Exception {
154 ParameterizedType withWildcardType = (ParameterizedType)
155 new TypeCapture<Comparable<? extends Iterable<String>>>() {}.capture();
156 TypeToken<?> wildcardType = TypeToken.of(withWildcardType.getActualTypeArguments()[0]);
157 assertEquals(String.class,
158 wildcardType.resolveType(Iterable.class.getTypeParameters()[0]).getType());
159 }
160
161 public void testGetTypes_noSuperclass() {
162 TypeToken<Object>.TypeSet types = new TypeToken<Object>() {}.getTypes();
163 assertThat(types).has().item(TypeToken.of(Object.class));
164 assertThat(types.rawTypes()).has().item(Object.class);
165 assertThat(types.interfaces()).isEmpty();
166 assertThat(types.interfaces().rawTypes()).isEmpty();
167 assertThat(types.classes()).has().item(TypeToken.of(Object.class));
168 assertThat(types.classes().rawTypes()).has().item(Object.class);
169 }
170
171 public void testGetTypes_fromInterface() {
172 TypeToken<Interface1>.TypeSet types = new TypeToken<Interface1>() {}.getTypes();
173 assertThat(types).has().item(TypeToken.of(Interface1.class));
174 assertThat(types.rawTypes()).has().item(Interface1.class);
175 assertThat(types.interfaces()).has().item(TypeToken.of(Interface1.class));
176 assertThat(types.interfaces().rawTypes()).has().item(Interface1.class);
177 assertThat(types.classes()).isEmpty();
178 assertThat(types.classes().rawTypes()).isEmpty();
179 }
180
181 public void testGetTypes_fromPrimitive() {
182 TypeToken<Integer>.TypeSet types = TypeToken.of(int.class).getTypes();
183 assertThat(types).has().item(TypeToken.of(int.class));
184 assertThat(types.rawTypes()).has().item(int.class);
185 assertThat(types.interfaces()).isEmpty();
186 assertThat(types.interfaces().rawTypes()).isEmpty();
187 assertThat(types.classes()).has().item(TypeToken.of(int.class));
188 assertThat(types.classes().rawTypes()).has().item(int.class);
189 }
190
191 public void testGetTypes_withInterfacesAndSuperclasses() {
192 abstract class Class2 extends Class1 implements Interface12 {}
193 abstract class Class3<T> extends Class2 implements Interface3<T> {}
194 TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
195 makeUnmodifiable(types).has().exactly(
196 new TypeToken<Class3<String>>() {},
197 new TypeToken<Interface3<String>>() {},
198 new TypeToken<Iterable<String>>() {},
199 TypeToken.of(Class2.class),
200 TypeToken.of(Interface12.class),
201 TypeToken.of(Interface1.class),
202 TypeToken.of(Interface2.class),
203 TypeToken.of(Class1.class),
204 TypeToken.of(Object.class));
205 makeUnmodifiable(types.interfaces()).has().exactly(
206 new TypeToken<Interface3<String>>() {},
207 TypeToken.of(Interface12.class),
208 TypeToken.of(Interface1.class),
209 TypeToken.of(Interface2.class),
210 new TypeToken<Iterable<String>>() {});
211 makeUnmodifiable(types.classes()).has().exactly(
212 new TypeToken<Class3<String>>() {},
213 TypeToken.of(Class2.class),
214 TypeToken.of(Class1.class),
215 TypeToken.of(Object.class));
216 assertSubtypeFirst(types);
217 }
218
219 public void testGetTypes_rawTypes_withInterfacesAndSuperclasses() {
220 abstract class Class2 extends Class1 implements Interface12 {}
221 abstract class Class3<T> extends Class2 implements Interface3<T> {}
222 TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
223 makeUnmodifiable(types.rawTypes()).has().exactly(
224 Class3.class, Interface3.class,
225 Iterable.class,
226 Class2.class,
227 Interface12.class,
228 Interface1.class,
229 Interface2.class,
230 Class1.class,
231 Object.class);
232 makeUnmodifiable(types.interfaces().rawTypes()).has().exactly(
233 Interface3.class,
234 Interface12.class,
235 Interface1.class,
236 Interface2.class,
237 Iterable.class);
238 makeUnmodifiable(types.classes().rawTypes()).has().exactly(
239 Class3.class,
240 Class2.class,
241 Class1.class,
242 Object.class);
243 assertSubtypeFirst(types);
244 }
245
246 public <A extends Class1 & Interface1, B extends A>
247 void testGetTypes_ignoresTypeVariablesByDefault() {
248 TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
249 makeUnmodifiable(types).has().exactly(
250 TypeToken.of(Interface1.class), TypeToken.of(Class1.class),
251 TypeToken.of(Object.class));
252 assertSubtypeFirst(types);
253 makeUnmodifiable(types.interfaces())
254 .has().exactly(TypeToken.of(Interface1.class))
255 .inOrder();
256 makeUnmodifiable(types.classes())
257 .has().exactly(TypeToken.of(Class1.class), TypeToken.of(Object.class))
258 .inOrder();
259 }
260
261 public <A extends Class1 & Interface1, B extends A>
262 void testGetTypes_rawTypes_ignoresTypeVariablesByDefault() {
263 TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
264 makeUnmodifiable(types.rawTypes())
265 .has().exactly(Interface1.class, Class1.class, Object.class);
266 makeUnmodifiable(types.interfaces().rawTypes())
267 .has().exactly(Interface1.class)
268 .inOrder();
269 makeUnmodifiable(types.classes().rawTypes())
270 .has().exactly(Class1.class, Object.class)
271 .inOrder();
272 }
273
274 public <A extends Interface1 & Interface2 & Interface3<String>>
275 void testGetTypes_manyBounds() {
276 TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<A>() {}.capture()).getTypes();
277 makeUnmodifiable(types.rawTypes())
278 .has().exactly(Interface1.class, Interface2.class, Interface3.class, Iterable.class);
279 }
280
281 private static void assertSubtypeFirst(TypeToken<?>.TypeSet types) {
282 assertSubtypeTokenBeforeSupertypeToken(types);
283 assertSubtypeTokenBeforeSupertypeToken(types.interfaces());
284 assertSubtypeTokenBeforeSupertypeToken(types.classes());
285 assertSubtypeBeforeSupertype(types.rawTypes());
286 assertSubtypeBeforeSupertype(types.interfaces().rawTypes());
287 assertSubtypeBeforeSupertype(types.classes().rawTypes());
288 }
289
290 private static void assertSubtypeTokenBeforeSupertypeToken(
291 Iterable<? extends TypeToken<?>> types) {
292 int i = 0;
293 for (TypeToken<?> left : types) {
294 int j = 0;
295 for (TypeToken<?> right : types) {
296 if (left.isAssignableFrom(right)) {
297 assertTrue(left + " should be after " + right, i >= j);
298 }
299 j++;
300 }
301 i++;
302 }
303 }
304
305 private static void assertSubtypeBeforeSupertype(Iterable<? extends Class<?>> types) {
306 int i = 0;
307 for (Class<?> left : types) {
308 int j = 0;
309 for (Class<?> right : types) {
310 if (left.isAssignableFrom(right)) {
311 assertTrue(left + " should be after " + right, i >= j);
312 }
313 j++;
314 }
315 i++;
316 }
317 }
318
319
320
321 public void testAssertSubtypeTokenBeforeSupertypeToken_empty() {
322 assertSubtypeTokenBeforeSupertypeToken(ImmutableList.<TypeToken<?>>of());
323 }
324
325 public void testAssertSubtypeTokenBeforeSupertypeToken_oneType() {
326 assertSubtypeTokenBeforeSupertypeToken(ImmutableList.of(TypeToken.of(String.class)));
327 }
328
329 public void testAssertSubtypeTokenBeforeSupertypeToken_subtypeFirst() {
330 assertSubtypeTokenBeforeSupertypeToken(
331 ImmutableList.of(TypeToken.of(String.class), TypeToken.of(CharSequence.class)));
332 }
333
334 public void testAssertSubtypeTokenBeforeSupertypeToken_supertypeFirst() {
335 try {
336 assertSubtypeTokenBeforeSupertypeToken(
337 ImmutableList.of(TypeToken.of(CharSequence.class), TypeToken.of(String.class)));
338 } catch (AssertionError expected) {
339 return;
340 }
341 fail();
342 }
343
344 public void testAssertSubtypeTokenBeforeSupertypeToken_duplicate() {
345 try {
346 assertSubtypeTokenBeforeSupertypeToken(
347 ImmutableList.of(TypeToken.of(String.class), TypeToken.of(String.class)));
348 } catch (AssertionError expected) {
349 return;
350 }
351 fail();
352 }
353
354 public void testAssertSubtypeBeforeSupertype_empty() {
355 assertSubtypeBeforeSupertype(ImmutableList.<Class<?>>of());
356 }
357
358 public void testAssertSubtypeBeforeSupertype_oneType() {
359 assertSubtypeBeforeSupertype(ImmutableList.of(String.class));
360 }
361
362 public void testAssertSubtypeBeforeSupertype_subtypeFirst() {
363 assertSubtypeBeforeSupertype(
364 ImmutableList.of(String.class, CharSequence.class));
365 }
366
367 public void testAssertSubtypeBeforeSupertype_supertypeFirst() {
368 try {
369 assertSubtypeBeforeSupertype(
370 ImmutableList.of(CharSequence.class, String.class));
371 } catch (AssertionError expected) {
372 return;
373 }
374 fail();
375 }
376
377 public void testAssertSubtypeBeforeSupertype_duplicate() {
378 try {
379 assertSubtypeBeforeSupertype(
380 ImmutableList.of(String.class, String.class));
381 } catch (AssertionError expected) {
382 return;
383 }
384 fail();
385 }
386
387 public void testGetGenericSuperclass_noSuperclass() {
388 assertNull(new TypeToken<Object>() {}.getGenericSuperclass());
389 assertEquals(TypeToken.of(Object.class),
390 new TypeToken<Object[]>() {}.getGenericSuperclass());
391 assertNull(new TypeToken<List<String>>() {}.getGenericSuperclass());
392 assertEquals(TypeToken.of(Object.class),
393 new TypeToken<List<String>[]>() {}.getGenericSuperclass());
394 }
395
396 public void testGetGenericSuperclass_withSuperclass() {
397 TypeToken<? super ArrayList<String>> superToken =
398 new TypeToken<ArrayList<String>>() {}.getGenericSuperclass();
399 assertEquals(ArrayList.class.getSuperclass(), superToken.getRawType());
400 assertEquals(String.class,
401 ((ParameterizedType) superToken.getType()).getActualTypeArguments()[0]);
402 assertEquals(TypeToken.of(Base.class), TypeToken.of(Sub.class).getGenericSuperclass());
403 assertEquals(TypeToken.of(Object.class), TypeToken.of(Sub[].class).getGenericSuperclass());
404 }
405
406 public <T> void testGetGenericSuperclass_typeVariable_unbounded() {
407 assertEquals(TypeToken.of(Object.class),
408 TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
409 assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
410 }
411
412 public <T extends ArrayList<String> & CharSequence>
413 void testGetGenericSuperclass_typeVariable_boundIsClass() {
414 assertEquals(new TypeToken<ArrayList<String>>() {},
415 TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
416 assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
417 }
418
419 public <T extends Enum<T> & CharSequence>
420 void testGetGenericSuperclass_typeVariable_boundIsFBoundedClass() {
421 assertEquals(new TypeToken<Enum<T>>() {},
422 TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
423 assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
424 }
425
426 public <T extends List<String> & CharSequence>
427 void testGetGenericSuperclass_typeVariable_boundIsInterface() {
428 assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
429 assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
430 }
431
432 public <T extends ArrayList<String> & CharSequence, T1 extends T>
433 void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndClass() {
434 assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
435 TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
436 assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
437 }
438
439 public <T extends List<String> & CharSequence, T1 extends T>
440 void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndInterface() {
441 assertNull(TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
442 assertEquals(TypeToken.of(Object.class), new TypeToken<T1[]>() {}.getGenericSuperclass());
443 }
444
445 public void testGetGenericSuperclass_wildcard_lowerBounded() {
446 assertEquals(TypeToken.of(Object.class),
447 TypeToken.of(Types.supertypeOf(String.class)).getGenericSuperclass());
448 assertEquals(new TypeToken<Object>() {},
449 TypeToken.of(Types.supertypeOf(String[].class)).getGenericSuperclass());
450 assertEquals(new TypeToken<Object>() {},
451 TypeToken.of(Types.supertypeOf(CharSequence.class)).getGenericSuperclass());
452 }
453
454 public void testGetGenericSuperclass_wildcard_boundIsClass() {
455 assertEquals(TypeToken.of(Object.class),
456 TypeToken.of(Types.subtypeOf(Object.class)).getGenericSuperclass());
457 assertEquals(new TypeToken<Object[]>() {},
458 TypeToken.of(Types.subtypeOf(Object[].class)).getGenericSuperclass());
459 }
460
461 public void testGetGenericSuperclass_wildcard_boundIsInterface() {
462 assertNull(TypeToken.of(Types.subtypeOf(CharSequence.class)).getGenericSuperclass());
463 assertEquals(new TypeToken<CharSequence[]>() {},
464 TypeToken.of(Types.subtypeOf(CharSequence[].class)).getGenericSuperclass());
465 }
466
467 public <T> void testGetGenericInterfaces_typeVariable_unbounded() {
468 assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()).isEmpty();
469 assertHasArrayInterfaces(new TypeToken<T[]>() {});
470 }
471
472 public <T extends NoInterface> void testGetGenericInterfaces_typeVariable_boundIsClass() {
473 assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()).isEmpty();
474 assertHasArrayInterfaces(new TypeToken<T[]>() {});
475 }
476
477 public <T extends NoInterface&Iterable<String>>
478 void testGetGenericInterfaces_typeVariable_boundsAreClassWithInterface() {
479 makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
480 .has().exactly(new TypeToken<Iterable<String>>() {});
481 assertHasArrayInterfaces(new TypeToken<T[]>() {});
482 }
483
484 public <T extends CharSequence&Iterable<String>>
485 void testGetGenericInterfaces_typeVariable_boundsAreInterfaces() {
486 makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
487 .has().exactly(TypeToken.of(CharSequence.class), new TypeToken<Iterable<String>>() {});
488 assertHasArrayInterfaces(new TypeToken<T[]>() {});
489 }
490
491 public <T extends CharSequence&Iterable<T>>
492 void testGetGenericInterfaces_typeVariable_boundsAreFBoundedInterfaces() {
493 makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
494 .has().exactly(TypeToken.of(CharSequence.class), new TypeToken<Iterable<T>>() {});
495 assertHasArrayInterfaces(new TypeToken<T[]>() {});
496 }
497
498 public <T extends Base&Iterable<T>>
499 void testGetGenericInterfaces_typeVariable_boundsAreClassWithFBoundedInterface() {
500 makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
501 .has().exactly(new TypeToken<Iterable<T>>() {});
502 assertHasArrayInterfaces(new TypeToken<T[]>() {});
503 }
504
505 public <T extends NoInterface, T1 extends T, T2 extends T1>
506 void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndClass() {
507 assertThat(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces()).isEmpty();
508 assertHasArrayInterfaces(new TypeToken<T2[]>() {});
509 }
510
511 public <T extends Iterable<T>, T1 extends T, T2 extends T1>
512 void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndInterface() {
513 makeUnmodifiable(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces())
514 .has().exactly(TypeToken.of(new TypeCapture<T1>() {}.capture()));
515 assertHasArrayInterfaces(new TypeToken<T2[]>() {});
516 }
517
518 public void testGetGenericInterfaces_wildcard_lowerBounded() {
519 assertThat(TypeToken.of(Types.supertypeOf(String.class)).getGenericInterfaces()).isEmpty();
520 assertThat(TypeToken.of(Types.supertypeOf(String[].class)).getGenericInterfaces()).isEmpty();
521 }
522
523 public void testGetGenericInterfaces_wildcard_boundIsClass() {
524 assertThat(TypeToken.of(Types.subtypeOf(Object.class)).getGenericInterfaces()).isEmpty();
525 assertThat(TypeToken.of(Types.subtypeOf(Object[].class)).getGenericInterfaces()).isEmpty();
526 }
527
528 public void testGetGenericInterfaces_wildcard_boundIsInterface() {
529 TypeToken<Iterable<String>> interfaceType = new TypeToken<Iterable<String>>() {};
530 makeUnmodifiable(TypeToken.of(Types.subtypeOf(interfaceType.getType())).getGenericInterfaces())
531 .has().exactly(interfaceType);
532 assertHasArrayInterfaces(new TypeToken<Iterable<String>[]>() {});
533 }
534
535 public void testGetGenericInterfaces_noInterface() {
536 assertThat(new TypeToken<NoInterface>() {}.getGenericInterfaces()).isEmpty();
537 assertHasArrayInterfaces(new TypeToken<NoInterface[]>() {});
538 }
539
540 public void testGetGenericInterfaces_withInterfaces() {
541 Map<Class<?>, Type> interfaceMap = Maps.newHashMap();
542 for (TypeToken<?> interfaceType:
543 new TypeToken<Implementation<Integer, String>>() {}.getGenericInterfaces()) {
544 interfaceMap.put(interfaceType.getRawType(), interfaceType.getType());
545 }
546 assertEquals(ImmutableMap.of(
547 Iterable.class, new TypeToken<Iterable<String>>() {}.getType(),
548 Map.class, new TypeToken<Map<Integer, String>>() {}.getType()),
549 interfaceMap);
550 }
551
552 private interface Interface1 {}
553 private interface Interface2 {}
554 private interface Interface3<T> extends Iterable<T> {}
555 private interface Interface12 extends Interface1, Interface2 {}
556 private static class Class1 implements Interface1 {}
557
558 private static final class NoInterface {}
559
560 private abstract static class Implementation<K, V>
561 implements Iterable<V>, Map<K, V> {}
562
563 private abstract static class First<T> {}
564
565 private abstract static class Second<D> extends First<D> {}
566
567 private abstract static class Third<T, D> extends Second<T> {}
568
569 private abstract static class Fourth<T, D> extends Third<D, T> {}
570
571 private static class ConcreteIS extends Fourth<Integer, String> {}
572
573 private static class ConcreteSI extends Fourth<String, Integer> {}
574
575 public void testAssignableClassToClass() {
576 @SuppressWarnings("rawtypes")
577 TypeToken<List> tokL = new TypeToken<List>() {};
578 assertTrue(tokL.isAssignableFrom(List.class));
579 assertTrue(tokL.isAssignableFrom(ArrayList.class));
580 assertFalse(tokL.isAssignableFrom(List[].class));
581
582 TypeToken<Number> tokN = new TypeToken<Number>() {};
583 assertTrue(tokN.isAssignableFrom(Number.class));
584 assertTrue(tokN.isAssignableFrom(Integer.class));
585 }
586
587 public <T> void testAssignableParameterizedTypeToObject() {
588 assertTrue(TypeToken.of(Object.class).isAssignableFrom(
589 TypeToken.of(new TypeCapture<T>() {}.capture())));
590 assertFalse(TypeToken.of(int.class).isAssignableFrom(
591 TypeToken.of(new TypeCapture<T>() {}.capture())));
592 }
593
594 public <T, T1 extends T> void testAssignableGenericArrayToGenericArray() {
595 assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[]>() {}));
596 assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T1[]>() {}));
597 assertFalse(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[][]>() {}));
598 }
599
600 public void testAssignableWildcardBoundedByArrayToArrayClass() throws Exception {
601 Type wildcardType = Types.subtypeOf(Object[].class);
602 assertTrue(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
603 assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
604 assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
605 assertFalse(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
606 }
607
608 public void testAssignableArrayClassToBoundedWildcard() throws Exception {
609 TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
610 TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
611 assertTrue(upperBounded.isAssignableFrom(Object[].class));
612 assertTrue(upperBounded.isAssignableFrom(Object[][].class));
613 assertTrue(upperBounded.isAssignableFrom(String[].class));
614 assertTrue(lowerBounded.isAssignableFrom(Object[].class));
615 assertTrue(lowerBounded.isAssignableFrom(Object.class));
616 assertFalse(lowerBounded.isAssignableFrom(Object[][].class));
617 assertFalse(lowerBounded.isAssignableFrom(String[].class));
618 }
619
620 public void testAssignableWildcardBoundedByIntArrayToArrayClass() throws Exception {
621 Type wildcardType = Types.subtypeOf(int[].class);
622 assertTrue(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
623 assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
624 assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
625 assertFalse(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
626 }
627
628 public void testAssignableWildcardToWildcard() throws Exception {
629 TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
630 TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
631 assertFalse(lowerBounded.isAssignableFrom(upperBounded));
632 assertTrue(lowerBounded.isAssignableFrom(lowerBounded));
633 assertTrue(upperBounded.isAssignableFrom(upperBounded));
634 assertFalse(upperBounded.isAssignableFrom(lowerBounded));
635 }
636
637 public <T> void testAssignableGenericArrayToArrayClass() {
638 assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[]>() {}));
639 assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[][]>() {}));
640 assertTrue(TypeToken.of(Object[][].class).isAssignableFrom(new TypeToken<T[][]>() {}));
641 }
642
643 public void testAssignableParameterizedTypeToClass() {
644 @SuppressWarnings("rawtypes")
645 TypeToken<List> tokL = new TypeToken<List>() {};
646 assertTrue(tokL.isAssignableFrom(StringList.class));
647 assertTrue(tokL.isAssignableFrom(
648 StringList.class.getGenericInterfaces()[0]));
649
650 @SuppressWarnings("rawtypes")
651 TypeToken<Second> tokS = new TypeToken<Second>() {};
652 assertTrue(tokS.isAssignableFrom(Second.class));
653 assertTrue(tokS.isAssignableFrom(Third.class.getGenericSuperclass()));
654 }
655
656 public void testAssignableArrayToClass() throws Exception {
657 @SuppressWarnings("rawtypes")
658 TypeToken<List[]> tokL = new TypeToken<List[]>() {};
659 assertTrue(tokL.isAssignableFrom(List[].class));
660 assertFalse(tokL.isAssignableFrom(List.class));
661
662 @SuppressWarnings("rawtypes")
663 TypeToken<Second[]> tokS = new TypeToken<Second[]>() {};
664 assertTrue(tokS.isAssignableFrom(Second[].class));
665 assertTrue(tokS.isAssignableFrom(Third[].class));
666 }
667
668 @SuppressWarnings("rawtypes")
669 public void testAssignableTokenToClass() {
670 TypeToken<List> tokL = new TypeToken<List>() {};
671 assertTrue(tokL.isAssignableFrom(new TypeToken<List>() {}));
672 assertTrue(tokL.isAssignableFrom(new TypeToken<List<String>>() {}));
673 assertTrue(tokL.isAssignableFrom(new TypeToken<List<?>>() {}));
674
675 TypeToken<Second> tokS = new TypeToken<Second>() {};
676 assertTrue(tokS.isAssignableFrom(new TypeToken<Second>() {}));
677 assertTrue(tokS.isAssignableFrom(new TypeToken<Third>() {}));
678 assertTrue(tokS.isAssignableFrom(
679 new TypeToken<Third<String, Integer>>() {}));
680
681 TypeToken<List[]> tokA = new TypeToken<List[]>() {};
682 assertTrue(tokA.isAssignableFrom(new TypeToken<List[]>() {}));
683 assertTrue(tokA.isAssignableFrom(new TypeToken<List<String>[]>() {}));
684 assertTrue(tokA.isAssignableFrom(new TypeToken<List<?>[]>() {}));
685 }
686
687 public void testAssignableClassToType() {
688 TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
689 assertTrue(tokenL.isAssignableFrom(StringList.class));
690 assertFalse(tokenL.isAssignableFrom(List.class));
691
692 TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
693 assertTrue(tokenF.isAssignableFrom(ConcreteIS.class));
694 assertFalse(tokenF.isAssignableFrom(ConcreteSI.class));
695 }
696
697 public void testAssignableClassToArrayType() {
698 TypeToken<List<String>[]> tokenL = new TypeToken<List<String>[]>() {};
699 assertTrue(tokenL.isAssignableFrom(StringList[].class));
700 assertFalse(tokenL.isAssignableFrom(List[].class));
701 }
702
703 public void testAssignableParameterizedTypeToType() {
704 TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
705 assertTrue(tokenL.isAssignableFrom(
706 StringList.class.getGenericInterfaces()[0]));
707 assertFalse(tokenL.isAssignableFrom(
708 IntegerList.class.getGenericInterfaces()[0]));
709
710 TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
711 assertTrue(tokenF.isAssignableFrom(
712 ConcreteIS.class.getGenericSuperclass()));
713 assertFalse(tokenF.isAssignableFrom(
714 ConcreteSI.class.getGenericSuperclass()));
715 }
716
717 public void testGenericArrayTypeToArrayType() throws Exception {
718 TypeToken<List<String>[]> tokL = new TypeToken<List<String>[]>() {};
719 TypeToken<ArrayList<String>[]> token =
720 new TypeToken<ArrayList<String>[]>() {};
721 assertTrue(tokL.isAssignableFrom(tokL.getType()));
722 assertTrue(tokL.isAssignableFrom(token.getType()));
723 }
724
725 public void testAssignableTokenToType() {
726 TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
727 assertTrue(tokenL.isAssignableFrom(new TypeToken<List<String>>() {}));
728 assertTrue(tokenL.isAssignableFrom(new TypeToken<ArrayList<String>>() {}));
729 assertTrue(tokenL.isAssignableFrom(new TypeToken<StringList>() {}));
730
731 TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
732 assertTrue(tokenF.isAssignableFrom(new TypeToken<Second<String>>() {}));
733 assertTrue(tokenF.isAssignableFrom(
734 new TypeToken<Third<String, Integer>>() {}));
735 assertFalse(tokenF.isAssignableFrom(
736 new TypeToken<Third<Integer, String>>() {}));
737 assertTrue(tokenF.isAssignableFrom(
738 new TypeToken<Fourth<Integer, String>>() {}));
739 assertFalse(tokenF.isAssignableFrom(
740 new TypeToken<Fourth<String, Integer>>() {}));
741 assertTrue(tokenF.isAssignableFrom(new TypeToken<ConcreteIS>() {}));
742 assertFalse(tokenF.isAssignableFrom(new TypeToken<ConcreteSI>() {}));
743 }
744
745 public void testAssignableWithWildcards() {
746 TypeToken<?> unboundedToken = new TypeToken<List<?>>() {};
747 TypeToken<?> upperBoundToken = new TypeToken<List<? extends Number>>() {};
748 TypeToken<?> lowerBoundToken = new TypeToken<List<? super Number>>() {};
749 TypeToken<?> concreteToken = new TypeToken<List<Number>>() {};
750 TypeToken<?> subtypeToken = new TypeToken<List<Integer>>() {};
751 TypeToken<?> supertypeToken = new TypeToken<List<Serializable>>() {};
752 List<TypeToken<?>> allTokens = ImmutableList.of(
753 unboundedToken, upperBoundToken, lowerBoundToken,
754 concreteToken, subtypeToken, supertypeToken);
755
756 for (TypeToken<?> typeToken : allTokens) {
757 assertTrue(typeToken.toString(), unboundedToken.isAssignableFrom(typeToken));
758 }
759
760 assertFalse(upperBoundToken.isAssignableFrom(unboundedToken));
761 assertTrue(upperBoundToken.isAssignableFrom(upperBoundToken));
762 assertFalse(upperBoundToken.isAssignableFrom(lowerBoundToken));
763 assertTrue(upperBoundToken.isAssignableFrom(concreteToken));
764 assertTrue(upperBoundToken.isAssignableFrom(subtypeToken));
765 assertFalse(upperBoundToken.isAssignableFrom(supertypeToken));
766
767 assertFalse(lowerBoundToken.isAssignableFrom(unboundedToken));
768 assertFalse(lowerBoundToken.isAssignableFrom(upperBoundToken));
769 assertTrue(lowerBoundToken.isAssignableFrom(lowerBoundToken));
770 assertTrue(lowerBoundToken.isAssignableFrom(concreteToken));
771 assertFalse(lowerBoundToken.isAssignableFrom(subtypeToken));
772 assertTrue(lowerBoundToken.isAssignableFrom(supertypeToken));
773
774 for (TypeToken<?> typeToken : allTokens) {
775 assertEquals(typeToken.toString(),
776 typeToken == concreteToken, concreteToken.isAssignableFrom(typeToken));
777 }
778
779 for (TypeToken<?> typeToken : allTokens) {
780 assertEquals(typeToken.toString(),
781 typeToken == subtypeToken, subtypeToken.isAssignableFrom(typeToken));
782 }
783
784 for (TypeToken<?> typeToken : allTokens) {
785 assertEquals(typeToken.toString(),
786 typeToken == supertypeToken, supertypeToken.isAssignableFrom(typeToken));
787 }
788 }
789
790 public <N1 extends Number, N2 extends Number, N11 extends N1>
791 void testIsAssignableFrom_typeVariable() {
792 assertAssignable(TypeToken.of(new TypeCapture<N1>() {}.capture()),
793 TypeToken.of(new TypeCapture<N1>() {}.capture()));
794 assertNotAssignable(new TypeToken<List<N11>>() {},
795 new TypeToken<List<N1>>() {});
796 assertNotAssignable(new TypeToken<Number>() {},
797 TypeToken.of(new TypeCapture<N1>() {}.capture()));
798 assertAssignable(TypeToken.of(new TypeCapture<N11>() {}.capture()),
799 TypeToken.of(new TypeCapture<N1>() {}.capture()));
800 assertNotAssignable(TypeToken.of(new TypeCapture<N2>() {}.capture()),
801 TypeToken.of(new TypeCapture<N1>() {}.capture()));
802 }
803
804 public <N1 extends Number, N2 extends Number, N11 extends N1>
805 void testIsAssignableFrom_equalWildcardTypes() {
806 assertAssignable(new TypeToken<List<? extends N1>>() {},
807 new TypeToken<List<? extends N1>>() {});
808 assertAssignable(new TypeToken<List<? super N1>>() {},
809 new TypeToken<List<? super N1>>() {});
810 assertAssignable(new TypeToken<List<? extends Number>>() {},
811 new TypeToken<List<? extends Number>>() {});
812 assertAssignable(new TypeToken<List<? super Number>>() {},
813 new TypeToken<List<? super Number>>() {});
814 }
815
816 public <N> void testIsAssignableFrom_wildcard_noBound() {
817 assertAssignable(new TypeToken<List<? super N>>() {},
818 new TypeToken<List<?>>() {});
819 assertAssignable(new TypeToken<List<N>>() {},
820 new TypeToken<List<?>>() {});
821 }
822
823 public <N1 extends Number, N2 extends Number, N11 extends N1>
824 void testIsAssignableFrom_wildcardType_upperBoundMatch() {
825
826 assertAssignable(new TypeToken<List<N11>>() {},
827 new TypeToken<List<? extends N1>>() {});
828 assertNotAssignable(new TypeToken<List<N1>>() {},
829 new TypeToken<List<? extends N11>>() {});
830 assertNotAssignable(new TypeToken<List<Number>>() {},
831 new TypeToken<List<? extends N11>>() {});
832
833
834 assertAssignable(new TypeToken<List<N1>>() {},
835 new TypeToken<List<? extends Number>>() {});
836 assertAssignable(new TypeToken<ArrayList<N1>>() {},
837 new TypeToken<List<? extends Number>>() {});
838 assertAssignable(new TypeToken<List<? extends N11>>() {},
839 new TypeToken<List<? extends Number>>() {});
840 }
841
842 public <N1 extends Number, N2 extends Number, N11 extends N1>
843 void testIsAssignableFrom_wildcardType_lowerBoundMatch() {
844
845 assertAssignable(new TypeToken<List<N1>>() {},
846 new TypeToken<List<? super N11>>() {});
847 assertAssignable(new TypeToken<ArrayList<Number>>() {},
848 new TypeToken<List<? super N1>>() {});
849 assertNotAssignable(new TypeToken<ArrayList<? super N11>>() {},
850 new TypeToken<List<? super Number>>() {});
851 assertAssignable(new TypeToken<ArrayList<? super N1>>() {},
852 new TypeToken<List<? super N11>>() {});
853 assertAssignable(new TypeToken<ArrayList<? super Number>>() {},
854 new TypeToken<List<? super N11>>() {});
855
856
857 assertNotAssignable(new TypeToken<ArrayList<N11>>() {},
858 new TypeToken<List<? super Number>>() {});
859 assertAssignable(new TypeToken<ArrayList<Number>>() {},
860 new TypeToken<List<? super Number>>() {});
861 assertAssignable(new TypeToken<ArrayList<Object>>() {},
862 new TypeToken<List<? super Number>>() {});
863 }
864
865 public <L extends List<R>, R extends List<L>>
866 void testIsAssignableFrom_recursiveTypeVariableBounds() {
867 assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
868 TypeToken.of(new TypeCapture<L>() {}.capture()));
869 assertNotAssignable(TypeToken.of(new TypeCapture<R>() {}.capture()),
870 TypeToken.of(new TypeCapture<L>() {}.capture()));
871 assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
872 new TypeToken<List<R>>() {});
873 }
874
875 public void testIsAssignableFrom_resolved() {
876 assertFalse(Assignability.of().isAssignable());
877 assertTrue(new Assignability<Integer, Integer>() {}.isAssignable());
878 assertTrue(new Assignability<Integer, Object>() {}.isAssignable());
879 assertFalse(new Assignability<Integer, String>() {}.isAssignable());
880 TypeTokenTest.<Number, Integer>assignabilityTestWithTypeVariables();
881 }
882
883 private static <N1 extends Number, N11 extends N1>
884 void assignabilityTestWithTypeVariables() {
885 assertTrue(new Assignability<N11, N1>() {}.isAssignable());
886 assertTrue(new Assignability<N11, Number>() {}.isAssignable());
887 assertFalse(new Assignability<Number, N11>() {}.isAssignable());
888 }
889
890 public void testIsArray_arrayClasses() {
891 assertTrue(TypeToken.of(Object[].class).isArray());
892 assertTrue(TypeToken.of(Object[][].class).isArray());
893 assertTrue(TypeToken.of(char[].class).isArray());
894 assertTrue(TypeToken.of(char[][].class).isArray());
895 assertTrue(TypeToken.of(byte[].class).isArray());
896 assertTrue(TypeToken.of(short[].class).isArray());
897 assertTrue(TypeToken.of(int[].class).isArray());
898 assertTrue(TypeToken.of(long[].class).isArray());
899 assertTrue(TypeToken.of(float[].class).isArray());
900 assertTrue(TypeToken.of(double[].class).isArray());
901 assertFalse(TypeToken.of(Object.class).isArray());
902 assertFalse(TypeToken.of(void.class).isArray());
903 }
904
905 public <T> void testIsArray_genericArrayClasses() {
906 assertFalse(TypeToken.of(new TypeCapture<T>() {}.capture()).isArray());
907 assertTrue(new TypeToken<T[]>() {}.isArray());
908 assertTrue(new TypeToken<T[][]>() {}.isArray());
909 }
910
911 public void testIsArray_wildcardType() throws Exception {
912 assertTrue(TypeToken.of(Types.subtypeOf(Object[].class)).isArray());
913 assertTrue(TypeToken.of(Types.subtypeOf(int[].class)).isArray());
914 assertFalse(TypeToken.of(Types.subtypeOf(Object.class)).isArray());
915 assertFalse(TypeToken.of(Types.supertypeOf(Object[].class)).isArray());
916 }
917
918 public <T extends Integer> void testPrimitiveWrappingAndUnwrapping() {
919 for (Class<?> type : Primitives.allPrimitiveTypes()) {
920 assertIsPrimitive(TypeToken.of(type));
921 }
922 for (Class<?> type : Primitives.allWrapperTypes()) {
923 assertIsWrapper(TypeToken.of(type));
924 }
925 assertNotPrimitiveNorWrapper(TypeToken.of(String.class));
926 assertNotPrimitiveNorWrapper(TypeToken.of(Object[].class));
927 assertNotPrimitiveNorWrapper(TypeToken.of(Types.subtypeOf(Object.class)));
928 assertNotPrimitiveNorWrapper(new TypeToken<List<String>>() {});
929 assertNotPrimitiveNorWrapper(TypeToken.of(new TypeCapture<T>() {}.capture()));
930 }
931
932 public void testGetComponentType_arrayClasses() {
933 assertEquals(Object.class, TypeToken.of(Object[].class).getComponentType().getType());
934 assertEquals(Object[].class, TypeToken.of(Object[][].class).getComponentType().getType());
935 assertEquals(char.class, TypeToken.of(char[].class).getComponentType().getType());
936 assertEquals(char[].class, TypeToken.of(char[][].class).getComponentType().getType());
937 assertEquals(byte.class, TypeToken.of(byte[].class).getComponentType().getType());
938 assertEquals(short.class, TypeToken.of(short[].class).getComponentType().getType());
939 assertEquals(int.class, TypeToken.of(int[].class).getComponentType().getType());
940 assertEquals(long.class, TypeToken.of(long[].class).getComponentType().getType());
941 assertEquals(float.class, TypeToken.of(float[].class).getComponentType().getType());
942 assertEquals(double.class, TypeToken.of(double[].class).getComponentType().getType());
943 assertNull(TypeToken.of(Object.class).getComponentType());
944 assertNull(TypeToken.of(void.class).getComponentType());
945 }
946
947 public <T> void testGetComponentType_genericArrayClasses() {
948 assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getComponentType());
949 assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
950 new TypeToken<T[]>() {}.getComponentType());
951 assertEquals(new TypeToken<T[]>() {}, new TypeToken<T[][]>() {}.getComponentType());
952 }
953
954 public void testGetComponentType_wildcardType() throws Exception {
955 assertEquals(Types.subtypeOf(Object.class),
956 TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType());
957 assertEquals(Types.subtypeOf(Object[].class),
958 Types.newArrayType(
959 TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType()));
960 assertEquals(int.class,
961 TypeToken.of(Types.subtypeOf(int[].class)).getComponentType().getType());
962 assertNull(TypeToken.of(Types.subtypeOf(Object.class)).getComponentType());
963 assertNull(TypeToken.of(Types.supertypeOf(Object[].class)).getComponentType());
964 }
965
966 private interface NumberList<T extends Number> {}
967
968 public void testImplicitUpperBoundForWildcards() {
969 assertAssignable(
970 new TypeToken<NumberList<? extends Number>>() {},
971 new TypeToken<NumberList<?>>() {});
972 assertAssignable(
973 new TypeToken<NumberList<? super Integer>>() {},
974 new TypeToken<NumberList<?>>() {});
975 }
976
977 public <T extends Readable & Appendable> void testMultiBound() {
978 assertAssignable(new TypeToken<List<T>>() {},
979 new TypeToken<List<? extends Readable>>() {});
980 assertAssignable(new TypeToken<List<T>>() {},
981 new TypeToken<List<? extends Appendable>>() {});
982 }
983
984 public void testToGenericType() {
985 assertEquals(TypeToken.of(String.class), TypeToken.toGenericType(String.class));
986 assertEquals(new TypeToken<int[]>() {}, TypeToken.toGenericType(int[].class));
987 @SuppressWarnings("rawtypes")
988 TypeToken<? extends Iterable> genericType = TypeToken.toGenericType(Iterable.class);
989 assertEquals(Iterable.class, genericType.getRawType());
990 assertEquals(Types.newParameterizedType(Iterable.class, Iterable.class.getTypeParameters()[0]),
991 genericType.getType());
992 }
993
994 private interface ListIterable<T> extends Iterable<List<T>> {}
995 private interface StringListIterable extends ListIterable<String> {}
996 private interface ListArrayIterable<T> extends Iterable<List<T>[]> {}
997 private interface StringListArrayIterable extends ListIterable<String> {}
998
999 public void testGetSupertype_withTypeVariable() {
1000 ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
1001 Types.newParameterizedType(List.class, ListIterable.class.getTypeParameters()[0]));
1002 assertEquals(expectedType,
1003 TypeToken.of(ListIterable.class).getSupertype(Iterable.class).getType());
1004 }
1005
1006 public void testGetSupertype_withoutTypeVariable() {
1007 ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
1008 Types.newParameterizedType(List.class, String.class));
1009 assertEquals(expectedType,
1010 TypeToken.of(StringListIterable.class).getSupertype(Iterable.class).getType());
1011 }
1012
1013 public void testGetSupertype_chained() {
1014 @SuppressWarnings("unchecked")
1015 TypeToken<ListIterable<String>> listIterableType = (TypeToken<ListIterable<String>>)
1016 TypeToken.of(StringListIterable.class).getSupertype(ListIterable.class);
1017 ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
1018 Types.newParameterizedType(List.class, String.class));
1019 assertEquals(expectedType, listIterableType.getSupertype(Iterable.class).getType());
1020 }
1021
1022 public void testGetSupertype_withArray() {
1023 assertEquals(new TypeToken<Iterable<List<String>>[]>() {},
1024 TypeToken.of(StringListIterable[].class).getSupertype(Iterable[].class));
1025 assertEquals(int[].class, TypeToken.of(int[].class).getSupertype(int[].class).getType());
1026 assertEquals(Object.class, TypeToken.of(int[].class).getSupertype(Object.class).getType());
1027 assertEquals(int[][].class, TypeToken.of(int[][].class).getSupertype(int[][].class).getType());
1028 assertEquals(Object[].class,
1029 TypeToken.of(String[].class).getSupertype(Object[].class).getType());
1030 assertEquals(Object.class, TypeToken.of(String[].class).getSupertype(Object.class).getType());
1031 }
1032
1033 public void testGetSupertype_fromWildcard() {
1034 @SuppressWarnings("unchecked")
1035 TypeToken<? extends List<String>> type = (TypeToken<? extends List<String>>)
1036 TypeToken.of(Types.subtypeOf(new TypeToken<List<String>>() {}.getType()));
1037 assertEquals(new TypeToken<Iterable<String>>() {}, type.getSupertype(Iterable.class));
1038 }
1039
1040 public <T extends Iterable<String>> void testGetSupertype_fromTypeVariable() {
1041 @SuppressWarnings("unchecked")
1042 TypeToken<T> typeVariableToken = (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture());
1043 assertEquals(new TypeToken<Iterable<String>>() {},
1044 typeVariableToken.getSupertype(Iterable.class));
1045 }
1046
1047 @SuppressWarnings("rawtypes")
1048 public void testGetSupertype_fromRawClass() {
1049 assertEquals(Types.newParameterizedType(Iterable.class, List.class.getTypeParameters()[0]),
1050 new TypeToken<List>() {}.getSupertype(Iterable.class).getType());
1051 }
1052
1053 @SuppressWarnings({"rawtypes", "unchecked"})
1054 public void testGetSupertype_notSupertype() {
1055 try {
1056 new TypeToken<List<String>>() {}.getSupertype((Class) String.class);
1057 fail();
1058 } catch (IllegalArgumentException expected) {}
1059 }
1060
1061 public void testGetSupertype_fromArray() {
1062 assertEquals(new TypeToken<Iterable<String>[]>() {},
1063 new TypeToken<List<String>[]>() {}.getSupertype(Iterable[].class));
1064 }
1065
1066 private interface ListMap<K, V> extends Map<K, List<V>> {}
1067
1068 public void testGetSupertype_fullyGenericType() {
1069 ParameterizedType expectedType = Types.newParameterizedType(Map.class,
1070 ListMap.class.getTypeParameters()[0],
1071 Types.newParameterizedType(List.class, ListMap.class.getTypeParameters()[1]));
1072 assertEquals(expectedType,
1073 TypeToken.of(ListMap.class).getSupertype(Map.class).getType());
1074 }
1075
1076 public void testGetSupertype_fullySpecializedType() {
1077 Type expectedType = new TypeToken<Map<String, List<Object>>>() {}.getType();
1078 assertEquals(expectedType,
1079 new TypeToken<ListMap<String, Object>>() {}.getSupertype(Map.class).getType());
1080 }
1081
1082 private interface StringListMap<V> extends ListMap<String, V> {}
1083
1084 public <V> void testGetSupertype_partiallySpecializedType() {
1085 Type expectedType = new TypeToken<Map<String, List<V>>>() {}.getType();
1086 assertEquals(expectedType,
1087 new TypeToken<StringListMap<V>>() {}.getSupertype(Map.class).getType());
1088 }
1089
1090 public void testGetSubtype_withTypeVariable() {
1091 assertEquals(new TypeToken<ListIterable<String>>() {},
1092 new TypeToken<Iterable<List<String>>>() {}.getSubtype(ListIterable.class));
1093 assertEquals(new TypeToken<ListArrayIterable<String>>() {},
1094 new TypeToken<Iterable<List<String>[]>>() {}.getSubtype(ListArrayIterable.class));
1095 assertEquals(new TypeToken<ListArrayIterable<String>[]>() {},
1096 new TypeToken<Iterable<List<String>[]>[]>() {}.getSubtype(ListArrayIterable[].class));
1097 }
1098
1099 public void testGetSubtype_withoutTypeVariable() {
1100 assertEquals(StringListIterable.class,
1101 TypeToken.of(Iterable.class).getSubtype(StringListIterable.class).getType());
1102 assertEquals(StringListIterable[].class,
1103 TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class).getType());
1104 assertEquals(TypeToken.of(StringListArrayIterable.class),
1105 new TypeToken<Iterable<List<String>>>() {}.getSubtype(StringListArrayIterable.class));
1106 assertEquals(TypeToken.of(StringListArrayIterable[].class),
1107 new TypeToken<Iterable<List<String>>[]>() {}.getSubtype(StringListArrayIterable[].class));
1108 }
1109
1110 public void testGetSubtype_withArray() {
1111 assertEquals(TypeToken.of(StringListIterable[].class),
1112 TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class));
1113 assertEquals(TypeToken.of(String[].class),
1114 TypeToken.of(Object[].class).getSubtype(String[].class));
1115 assertEquals(TypeToken.of(int[].class),
1116 TypeToken.of(Object.class).getSubtype(int[].class));
1117 }
1118
1119 public void testGetSubtype_fromWildcard() {
1120 @SuppressWarnings("unchecked")
1121 TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
1122 TypeToken.of(Types.supertypeOf(new TypeToken<Iterable<String>>() {}.getType()));
1123 assertEquals(new TypeToken<List<String>>() {}, type.getSubtype(List.class));
1124 }
1125
1126 public void testGetSubtype_fromWildcard_lowerBoundNotSupertype() {
1127 @SuppressWarnings("unchecked")
1128 TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
1129 TypeToken.of(Types.supertypeOf(new TypeToken<ImmutableList<String>>() {}.getType()));
1130 try {
1131 type.getSubtype(List.class);
1132 fail();
1133 } catch (IllegalArgumentException expected) {}
1134 }
1135
1136 public void testGetSubtype_fromWildcard_upperBounded() {
1137 @SuppressWarnings("unchecked")
1138 TypeToken<? extends Iterable<String>> type = (TypeToken<? extends Iterable<String>>)
1139 TypeToken.of(Types.subtypeOf(new TypeToken<Iterable<String>>() {}.getType()));
1140 try {
1141 type.getSubtype(Iterable.class);
1142 fail();
1143 } catch (IllegalArgumentException expected) {}
1144 }
1145
1146 public <T extends Iterable<String>> void testGetSubtype_fromTypeVariable() {
1147 try {
1148 TypeToken.of(new TypeCapture<T>() {}.capture()).getSubtype(List.class);
1149 fail();
1150 } catch (IllegalArgumentException expected) {}
1151 }
1152
1153 @SuppressWarnings("rawtypes")
1154 public void testGetSubtype_fromRawClass() {
1155 assertEquals(List.class, new TypeToken<Iterable>() {}.getSubtype(List.class).getType());
1156 }
1157
1158 public void testGetSubtype_fromArray() {
1159 assertEquals(new TypeToken<List<String>[]>() {},
1160 new TypeToken<Iterable<String>[]>() {}.getSubtype(List[].class));
1161 }
1162
1163 @SuppressWarnings("unchecked")
1164 public <T> void testWhere_circleRejected() {
1165 TypeToken<List<T>> type = new TypeToken<List<T>>() {};
1166 try {
1167 type.where(new TypeParameter<T>() {},
1168 (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture()));
1169 fail();
1170 } catch (IllegalArgumentException expected) {}
1171 }
1172
1173 public void testWhere() {
1174 assertEquals(
1175 new TypeToken<Map<String, Integer>>() {},
1176 mapOf(String.class, Integer.class));
1177 assertEquals(new TypeToken<int[]>() {}, arrayOf(int.class));
1178 assertEquals(int[].class, arrayOf(int.class).getRawType());
1179 }
1180
1181 @SuppressWarnings("unused")
1182 private static class Holder<T> {
1183 T element;
1184 List<T> list;
1185 List<T>[] matrix;
1186
1187 void setList(List<T> list) {
1188 this.list = list;
1189 }
1190 }
1191
1192 public void testWildcardCaptured_methodParameter_upperBound() throws Exception {
1193 TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
1194 TypeToken<?> parameterType = type.resolveType(
1195 Holder.class.getDeclaredMethod("setList", List.class).getGenericParameterTypes()[0]);
1196 assertEquals(List.class, parameterType.getRawType());
1197 assertFalse(parameterType.getType().toString(),
1198 parameterType.isAssignableFrom(new TypeToken<List<Integer>>() {}));
1199 }
1200
1201 public void testWildcardCaptured_field_upperBound() throws Exception {
1202 TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
1203 TypeToken<?> matrixType = type.resolveType(
1204 Holder.class.getDeclaredField("matrix").getGenericType());
1205 assertEquals(List[].class, matrixType.getRawType());
1206 assertThat(matrixType.getType())
1207 .isNotEqualTo(new TypeToken<List<?>[]>() {}.getType());
1208 }
1209
1210 public void testArrayClassPreserved() {
1211 assertEquals(int[].class, TypeToken.of(int[].class).getType());
1212 assertEquals(int[][].class, TypeToken.of(int[][].class).getType());
1213 assertEquals(String[].class, TypeToken.of(String[].class).getType());
1214 assertEquals(Integer.class, new TypeToken<Integer>() {}.getType());
1215 assertEquals(Integer.class, TypeToken.of(Integer.class).getType());
1216 }
1217
1218 public void testMethod_getOwnerType() throws NoSuchMethodException {
1219 Method sizeMethod = List.class.getMethod("size");
1220 assertEquals(TypeToken.of(List.class),
1221 TypeToken.of(List.class).method(sizeMethod).getOwnerType());
1222 assertEquals(new TypeToken<List<String>>() {},
1223 new TypeToken<List<String>>() {}.method(sizeMethod).getOwnerType());
1224 }
1225
1226 public void testMethod_notDeclaredByType() throws NoSuchMethodException {
1227 Method sizeMethod = Map.class.getMethod("size");
1228 try {
1229 TypeToken.of(List.class).method(sizeMethod);
1230 fail();
1231 } catch (IllegalArgumentException expected) {}
1232 }
1233
1234 public void testMethod_declaredBySuperclass() throws Exception {
1235 Method toStringMethod = Object.class.getMethod("toString");
1236 ImmutableList<String> list = ImmutableList.of("foo");
1237 assertEquals(list.toString(), TypeToken.of(List.class).method(toStringMethod).invoke(list));
1238 }
1239
1240 public <T extends Number & List<String>> void testMethod_returnType_resolvedAgainstTypeBound()
1241 throws NoSuchMethodException {
1242 Method getMethod = List.class.getMethod("get", int.class);
1243 Invokable<T, String> invokable = new TypeToken<T>(getClass()) {}
1244 .method(getMethod)
1245 .returning(String.class);
1246 assertEquals(TypeToken.of(String.class), invokable.getReturnType());
1247 }
1248
1249 public <T extends List<String>> void testMethod_parameterTypes()
1250 throws NoSuchMethodException {
1251 Method setMethod = List.class.getMethod("set", int.class, Object.class);
1252 Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(setMethod);
1253 ImmutableList<Parameter> params = invokable.getParameters();
1254 assertEquals(2, params.size());
1255 assertEquals(TypeToken.of(int.class), params.get(0).getType());
1256 assertEquals(TypeToken.of(String.class), params.get(1).getType());
1257 }
1258
1259 public void testMethod_equals() throws NoSuchMethodException {
1260 Method getMethod = List.class.getMethod("get", int.class);
1261 Method setMethod = List.class.getMethod("set", int.class, Object.class);
1262 new EqualsTester()
1263 .addEqualityGroup(Invokable.from(getMethod), Invokable.from(getMethod))
1264 .addEqualityGroup(Invokable.from(setMethod))
1265 .addEqualityGroup(new TypeToken<List<Integer>>() {}.method(getMethod))
1266 .addEqualityGroup(new TypeToken<List<String>>() {}.method(getMethod))
1267 .addEqualityGroup(new TypeToken<List<Integer>>() {}.method(setMethod))
1268 .addEqualityGroup(new TypeToken<List<String>>() {}.method(setMethod))
1269 .testEquals();
1270 }
1271
1272 private interface Loser<E extends Throwable> {
1273 void lose() throws E;
1274 }
1275
1276 public <T extends Loser<AssertionError>> void testMethod_exceptionTypes()
1277 throws NoSuchMethodException {
1278 Method failMethod = Loser.class.getMethod("lose");
1279 Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(failMethod);
1280 assertThat(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
1281 }
1282
1283 public void testConstructor_getOwnerType() throws NoSuchMethodException {
1284 @SuppressWarnings("rawtypes")
1285 Constructor<ArrayList> constructor = ArrayList.class.getConstructor();
1286 assertEquals(TypeToken.of(ArrayList.class),
1287 TypeToken.of(ArrayList.class).constructor(constructor).getOwnerType());
1288 assertEquals(new TypeToken<ArrayList<String>>() {},
1289 new TypeToken<ArrayList<String>>() {}.constructor(constructor).getOwnerType());
1290 }
1291
1292 public void testConstructor_notDeclaredByType() throws NoSuchMethodException {
1293 Constructor<String> constructor = String.class.getConstructor();
1294 try {
1295 TypeToken.of(Object.class).constructor(constructor);
1296 fail();
1297 } catch (IllegalArgumentException expected) {}
1298 }
1299
1300 public void testConstructor_declaredBySuperclass() throws NoSuchMethodException {
1301 Constructor<Object> constructor = Object.class.getConstructor();
1302 try {
1303 TypeToken.of(String.class).constructor(constructor);
1304 fail();
1305 } catch (IllegalArgumentException expected) {}
1306 }
1307
1308 public void testConstructor_equals() throws NoSuchMethodException {
1309 Constructor<?> defaultConstructor = ArrayList.class.getConstructor();
1310 Constructor<?> oneArgConstructor = ArrayList.class.getConstructor(int.class);
1311 new EqualsTester()
1312 .addEqualityGroup(Invokable.from(defaultConstructor), Invokable.from(defaultConstructor))
1313 .addEqualityGroup(Invokable.from(oneArgConstructor))
1314 .addEqualityGroup(new TypeToken<ArrayList<Integer>>() {}.constructor(defaultConstructor))
1315 .addEqualityGroup(new TypeToken<ArrayList<String>>() {}.constructor(defaultConstructor))
1316 .addEqualityGroup(new TypeToken<ArrayList<Integer>>() {}.constructor(oneArgConstructor))
1317 .addEqualityGroup(new TypeToken<ArrayList<String>>() {}.constructor(oneArgConstructor))
1318 .testEquals();
1319 }
1320
1321 private static class Container<T> {
1322 @SuppressWarnings("unused")
1323 public Container(T data) {}
1324 }
1325
1326 public <T extends Container<String>> void testConstructor_parameterTypes()
1327 throws NoSuchMethodException {
1328 @SuppressWarnings("rawtypes")
1329 Constructor<Container> constructor = Container.class.getConstructor(Object.class);
1330 Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
1331 ImmutableList<Parameter> params = invokable.getParameters();
1332 assertEquals(1, params.size());
1333 assertEquals(TypeToken.of(String.class), params.get(0).getType());
1334 }
1335
1336 private static class CannotConstruct<E extends Throwable> {
1337 @SuppressWarnings("unused")
1338 public CannotConstruct() throws E {}
1339 }
1340
1341 public <T extends CannotConstruct<AssertionError>> void testConstructor_exceptionTypes()
1342 throws NoSuchMethodException {
1343 @SuppressWarnings("rawtypes")
1344 Constructor<CannotConstruct> constructor = CannotConstruct.class.getConstructor();
1345 Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
1346 assertThat(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
1347 }
1348
1349 public void testRejectTypeVariable_class() {
1350 assertNoTypeVariable(String.class);
1351 assertNoTypeVariable(String[].class);
1352 assertNoTypeVariable(int[].class);
1353 }
1354
1355 public void testRejectTypeVariable_parameterizedType() {
1356 assertNoTypeVariable(new TypeCapture<Iterable<String>>() {}.capture());
1357 }
1358
1359 public void testRejectTypeVariable_wildcardType() {
1360 assertNoTypeVariable(
1361 new TypeCapture<Iterable<? extends String>>() {}.capture());
1362 assertNoTypeVariable(
1363 new TypeCapture<Iterable<? super String>>() {}.capture());
1364 }
1365
1366 public void testRejectTypeVariable_genericArrayType() {
1367 assertNoTypeVariable(
1368 new TypeCapture<Iterable<? extends String>[]>() {}.capture());
1369 }
1370
1371 public <T> void testRejectTypeVariable_withTypeVariable() {
1372 assertHasTypeVariable(new TypeCapture<T>() {}.capture());
1373 assertHasTypeVariable(new TypeCapture<T[]>() {}.capture());
1374 assertHasTypeVariable(new TypeCapture<Iterable<T>>() {}.capture());
1375 assertHasTypeVariable(new TypeCapture<Map<String, T>>() {}.capture());
1376 assertHasTypeVariable(
1377 new TypeCapture<Map<String, ? extends T>>() {}.capture());
1378 assertHasTypeVariable(
1379 new TypeCapture<Map<String, ? super T[]>>() {}.capture());
1380 }
1381
1382 private static class From<K> {
1383 class To<V> {
1384 Type type() {
1385 return new TypeToken<To<V>>(getClass()) {}.getType();
1386 }
1387 }
1388 }
1389
1390 public <T> void testRejectTypeVariable_withOwnerType() {
1391
1392 assertHasTypeVariable(new From<Integer>().new To<String>().type());
1393 assertHasTypeVariable(new From<T>().new To<String>().type());
1394 assertHasTypeVariable(new From<Integer>().new To<T>().type());
1395
1396
1397 assertHasTypeVariable(new From<Integer>() {}.new To<String>().type());
1398 assertHasTypeVariable(new From<T>() {}.new To<String>().type());
1399
1400
1401 assertNoTypeVariable(new From<Integer>().new To<String>() {}.type());
1402 assertHasTypeVariable(new From<Integer>().new To<T>() {}.type());
1403 assertHasTypeVariable(new From<T>().new To<String>() {}.type());
1404
1405
1406 assertHasTypeVariable(new From<T>() {}.new To<String>() {}.type());
1407 assertNoTypeVariable(new From<Integer>() {}.new To<String>() {}.type());
1408 assertHasTypeVariable(new From<Integer>() {}.new To<T>() {}.type());
1409 }
1410
1411 private static void assertHasTypeVariable(Type type) {
1412 try {
1413 TypeToken.of(type).rejectTypeVariables();
1414 fail("Should contain TypeVariable");
1415 } catch (IllegalArgumentException expected) {}
1416 }
1417
1418 private static void assertNoTypeVariable(Type type) {
1419 TypeToken.of(type).rejectTypeVariables();
1420 }
1421
1422 private abstract static class RawTypeConsistencyTester<T extends Enum<T> & CharSequence> {
1423 abstract T returningT();
1424 abstract void acceptT(T t);
1425 abstract <X extends T> X returningX();
1426 abstract <X> void acceptX(X x);
1427 abstract <T2 extends Enum<T2> & CharSequence> T2 returningT2();
1428 abstract <T2 extends CharSequence&Iterable<T2>> void acceptT2(T2 t2);
1429
1430 static void verifyConsitentRawType() {
1431 for (Method method : RawTypeConsistencyTester.class.getDeclaredMethods()) {
1432 assertEquals(method.getReturnType(), TypeToken.getRawType(method.getGenericReturnType()));
1433 for (int i = 0; i < method.getParameterTypes().length; i++) {
1434 assertEquals(method.getParameterTypes()[i],
1435 TypeToken.getRawType(method.getGenericParameterTypes()[i]));
1436 }
1437 }
1438 }
1439 }
1440
1441 public void testRawTypes() throws Exception {
1442 RawTypeConsistencyTester.verifyConsitentRawType();
1443 assertEquals(Object.class, TypeToken.getRawType(Types.subtypeOf(Object.class)));
1444 assertEquals(CharSequence.class, TypeToken.getRawType(Types.subtypeOf(CharSequence.class)));
1445 assertEquals(Object.class, TypeToken.getRawType(Types.supertypeOf(CharSequence.class)));
1446 }
1447
1448 private abstract static class IKnowMyType<T> {
1449 TypeToken<T> type() {
1450 return new TypeToken<T>(getClass()) {};
1451 }
1452 }
1453
1454 public void testTypeResolution() {
1455 assertEquals(String.class,
1456 new IKnowMyType<String>() {}.type().getType());
1457 assertEquals(new TypeToken<Map<String, Integer>>() {},
1458 new IKnowMyType<Map<String, Integer>>() {}.type());
1459 }
1460
1461 public <A extends Iterable<? extends String>, B extends A> void testSerializable() {
1462 reserialize(TypeToken.of(String.class));
1463 reserialize(TypeToken.of(String.class).getTypes());
1464 reserialize(TypeToken.of(String.class).getTypes().classes());
1465 reserialize(TypeToken.of(String.class).getTypes().interfaces());
1466 reserialize(TypeToken.of(String.class).getTypes().rawTypes());
1467 reserialize(TypeToken.of(String.class).getTypes().classes().rawTypes());
1468 reserialize(TypeToken.of(String.class).getTypes().interfaces().rawTypes());
1469 reserialize(new TypeToken<int[]>() {});
1470 reserialize(new TypeToken<Map<String, Integer>>() {});
1471 reserialize(new IKnowMyType<Map<? super String, ? extends int[]>>() {}.type());
1472 reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes().rawTypes());
1473 try {
1474 SerializableTester.reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()));
1475 fail();
1476 } catch (RuntimeException expected) {}
1477 }
1478
1479 public <A> void testSerializable_typeVariableNotSupported() {
1480 try {
1481 new ITryToSerializeMyTypeVariable<String>().go();
1482 fail();
1483 } catch (RuntimeException expected) {}
1484 }
1485
1486 private static class ITryToSerializeMyTypeVariable<T> {
1487 void go() {
1488 SerializableTester.reserialize(TypeToken.of(new TypeCapture<T>() {}.capture()));
1489 }
1490 }
1491
1492 private static <T> T reserialize(T object) {
1493 T copy = SerializableTester.reserialize(object);
1494 new EqualsTester()
1495 .addEqualityGroup(object, copy)
1496 .testEquals();
1497 return copy;
1498 }
1499
1500 public void testTypeResolutionAfterReserialized() {
1501 reserialize(new TypeToken<String>() {});
1502 reserialize(new TypeToken<Map<String, Integer>>() {});
1503 TypeToken<Map<String, Integer>> reserialized = reserialize(
1504 new TypeToken<Map<String, Integer>>() {});
1505 assertEquals(reserialized, substitute(reserialized, String.class));
1506 }
1507
1508 private static <T, X> TypeToken<T> substitute(TypeToken<T> type, Class<X> arg) {
1509 return type.where(new TypeParameter<X>() {}, arg);
1510 }
1511
1512 private abstract static class ToReproduceGenericSignatureFormatError<V> {
1513 private abstract class BaseOuter {
1514 abstract class BaseInner {}
1515 }
1516 private abstract class SubOuter extends BaseOuter {
1517 private abstract class SubInner extends BaseInner {}
1518 }
1519 }
1520
1521
1522 public void testDespiteGenericSignatureFormatError() {
1523 ImmutableSet.copyOf(
1524 TypeToken.of(ToReproduceGenericSignatureFormatError.SubOuter.SubInner.class)
1525 .getTypes()
1526 .rawTypes());
1527 }
1528
1529 private abstract static class Entry<K, V> {
1530 TypeToken<K> keyType() {
1531 return new TypeToken<K>(getClass()) {};
1532 }
1533 TypeToken<V> valueType() {
1534 return new TypeToken<V>(getClass()) {};
1535 }
1536 }
1537
1538
1539 public <A, B> void testEquals() {
1540 new EqualsTester()
1541 .addEqualityGroup(
1542 TypeToken.of(String.class),
1543 TypeToken.of(String.class),
1544 new Entry<String, Integer>() {}.keyType(),
1545 new Entry<Integer, String>() {}.valueType(),
1546 new TypeToken<String>() {},
1547 new TypeToken<String>() {})
1548 .addEqualityGroup(
1549 TypeToken.of(Integer.class),
1550 new TypeToken<Integer>() {},
1551 new Entry<Integer, String>() {}.keyType(),
1552 new Entry<String, Integer>() {}.valueType())
1553 .addEqualityGroup(
1554 new TypeToken<List<String>>() {},
1555 new TypeToken<List<String>>() {})
1556 .addEqualityGroup(
1557 new TypeToken<List<?>>() {},
1558 new TypeToken<List<?>>() {})
1559 .addEqualityGroup(
1560 new TypeToken<Map<A, ?>>() {},
1561 new TypeToken<Map<A, ?>>() {})
1562 .addEqualityGroup(
1563 new TypeToken<Map<B, ?>>() {})
1564 .addEqualityGroup(
1565 TypeToken.of(new TypeCapture<A>() {}.capture()),
1566 TypeToken.of(new TypeCapture<A>() {}.capture()))
1567 .addEqualityGroup(TypeToken.of(new TypeCapture<B>() {}.capture()))
1568 .testEquals();
1569 }
1570
1571
1572 public <T> void testToString() {
1573 assertEquals(String.class.getName(), new TypeToken<String>() {}.toString());
1574 assertEquals("T", TypeToken.of(new TypeCapture<T>() {}.capture()).toString());
1575 assertEquals("java.lang.String", new Entry<String, Integer>() {}.keyType().toString());
1576 }
1577
1578 private static <K, V> TypeToken<Map<K, V>> mapOf(Class<K> keyType, Class<V> valueType) {
1579 return new TypeToken<Map<K, V>>() {}
1580 .where(new TypeParameter<K>() {}, keyType)
1581 .where(new TypeParameter<V>() {}, valueType);
1582 }
1583
1584 private static <T> TypeToken<T[]> arrayOf(Class<T> componentType) {
1585 return new TypeToken<T[]>() {}
1586 .where(new TypeParameter<T>() {}, componentType);
1587 }
1588
1589 public <T> void testNulls() {
1590 new NullPointerTester()
1591 .testAllPublicStaticMethods(TypeToken.class);
1592 new NullPointerTester()
1593 .setDefault(TypeParameter.class, new TypeParameter<T>() {})
1594 .testAllPublicInstanceMethods(TypeToken.of(String.class));
1595 }
1596
1597 private static class Assignability<From, To> {
1598
1599 boolean isAssignable() {
1600 return new TypeToken<To>(getClass()) {}.isAssignableFrom(new TypeToken<From>(getClass()) {});
1601 }
1602
1603 static <From, To> Assignability<From, To> of() {
1604 return new Assignability<From, To>();
1605 }
1606 }
1607
1608 private static void assertAssignable(TypeToken<?> from, TypeToken<?> to) {
1609 assertTrue(
1610 from.getType() + " is expected to be assignable to " + to.getType(),
1611 to.isAssignableFrom(from));
1612 }
1613
1614 private static void assertNotAssignable(TypeToken<?> from, TypeToken<?> to) {
1615 assertFalse(
1616 from.getType() + " shouldn't be assignable to " + to.getType(),
1617 to.isAssignableFrom(from));
1618 }
1619
1620 private static void assertHasArrayInterfaces(TypeToken<?> arrayType) {
1621 assertEquals(arrayInterfaces(), ImmutableSet.copyOf(arrayType.getGenericInterfaces()));
1622 }
1623
1624 private static ImmutableSet<TypeToken<?>> arrayInterfaces() {
1625 ImmutableSet.Builder<TypeToken<?>> builder = ImmutableSet.builder();
1626 for (Class<?> interfaceType : Object[].class.getInterfaces()) {
1627 builder.add(TypeToken.of(interfaceType));
1628 }
1629 return builder.build();
1630 }
1631
1632 private static void assertIsPrimitive(TypeToken<?> type) {
1633 assertTrue(type.isPrimitive());
1634 assertNotWrapper(type);
1635 assertEquals(TypeToken.of(Primitives.wrap((Class<?>) type.getType())), type.wrap());
1636 }
1637
1638 private static void assertNotPrimitive(TypeToken<?> type) {
1639 assertFalse(type.isPrimitive());
1640 assertSame(type, type.wrap());
1641 }
1642
1643 private static void assertIsWrapper(TypeToken<?> type) {
1644 assertNotPrimitive(type);
1645 assertEquals(TypeToken.of(Primitives.unwrap((Class<?>) type.getType())), type.unwrap());
1646 }
1647
1648 private static void assertNotWrapper(TypeToken<?> type) {
1649 assertSame(type, type.unwrap());
1650 }
1651
1652 private static void assertNotPrimitiveNorWrapper(TypeToken<?> type) {
1653 assertNotPrimitive(type);
1654 assertNotWrapper(type);
1655 }
1656
1657 private interface BaseInterface {}
1658 private static class Base implements BaseInterface {}
1659 private static class Sub extends Base {}
1660
1661 private static CollectionSubject<?, Object, ?> makeUnmodifiable(Collection<?> actual) {
1662 return assertThat(Collections.<Object>unmodifiableCollection(actual));
1663 }
1664 }