17dd252788645e940eada959bdde927426e2531c9Paul Duffin/* 27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2011 The Guava Authors 37dd252788645e940eada959bdde927426e2531c9Paul Duffin * 47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License. 67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at 77dd252788645e940eada959bdde927426e2531c9Paul Duffin * 87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 97dd252788645e940eada959bdde927426e2531c9Paul Duffin * 107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software 117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and 147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License. 157dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 167dd252788645e940eada959bdde927426e2531c9Paul Duffin 177dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.reflect; 187dd252788645e940eada959bdde927426e2531c9Paul Duffin 197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static java.util.Arrays.asList; 200888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static org.truth0.Truth.ASSERT; 217dd252788645e940eada959bdde927426e2531c9Paul Duffin 220888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.Lists; 237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.EqualsTester; 247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.NullPointerTester; 257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.NullPointerTester.Visibility; 267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.SerializableTester; 277dd252788645e940eada959bdde927426e2531c9Paul Duffin 280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestCase; 290888a09821a98ac0680fad765217302858e70fa4Paul Duffin 307dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.GenericArrayType; 317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.GenericDeclaration; 327dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.ParameterizedType; 337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Type; 347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.TypeVariable; 357dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.WildcardType; 367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Arrays; 377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.HashMap; 387dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.List; 397dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map; 407dd252788645e940eada959bdde927426e2531c9Paul Duffin 417dd252788645e940eada959bdde927426e2531c9Paul Duffin/** 427dd252788645e940eada959bdde927426e2531c9Paul Duffin * Tests for {@link Types}. 437dd252788645e940eada959bdde927426e2531c9Paul Duffin * 447dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Ben Yu 457dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 467dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic class TypesTest extends TestCase { 477dd252788645e940eada959bdde927426e2531c9Paul Duffin 487dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_ownerTypeImplied() throws Exception { 497dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType jvmType = (ParameterizedType) 507dd252788645e940eada959bdde927426e2531c9Paul Duffin new TypeCapture<Map.Entry<String, Integer>>() {}.capture(); 517dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType ourType = Types.newParameterizedType( 527dd252788645e940eada959bdde927426e2531c9Paul Duffin Map.Entry.class, String.class, Integer.class); 537dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType, ourType); 547dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(Map.class, ourType.getOwnerType()); 557dd252788645e940eada959bdde927426e2531c9Paul Duffin } 567dd252788645e940eada959bdde927426e2531c9Paul Duffin 577dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType() { 587dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType jvmType = (ParameterizedType) 597dd252788645e940eada959bdde927426e2531c9Paul Duffin new TypeCapture<HashMap<String, int[][]>>() {}.capture(); 607dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType ourType = Types.newParameterizedType( 617dd252788645e940eada959bdde927426e2531c9Paul Duffin HashMap.class, String.class, int[][].class); 627dd252788645e940eada959bdde927426e2531c9Paul Duffin 637dd252788645e940eada959bdde927426e2531c9Paul Duffin new EqualsTester() 647dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(jvmType, ourType) 657dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 667dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType.toString(), ourType.toString()); 677dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType.hashCode(), ourType.hashCode()); 687dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(HashMap.class, ourType.getRawType()); 690888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ourType.getActualTypeArguments()) 707dd252788645e940eada959bdde927426e2531c9Paul Duffin .iteratesOverSequence(jvmType.getActualTypeArguments()); 717dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(Arrays.asList( 727dd252788645e940eada959bdde927426e2531c9Paul Duffin String.class, 737dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newArrayType(Types.newArrayType(int.class))), 747dd252788645e940eada959bdde927426e2531c9Paul Duffin Arrays.asList(ourType.getActualTypeArguments())); 757dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(null, ourType.getOwnerType()); 767dd252788645e940eada959bdde927426e2531c9Paul Duffin } 777dd252788645e940eada959bdde927426e2531c9Paul Duffin 787dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_nonStaticLocalClass() { 797dd252788645e940eada959bdde927426e2531c9Paul Duffin class LocalClass<T> {} 807dd252788645e940eada959bdde927426e2531c9Paul Duffin Type jvmType = new LocalClass<String>() {}.getClass().getGenericSuperclass(); 817dd252788645e940eada959bdde927426e2531c9Paul Duffin Type ourType = Types.newParameterizedType(LocalClass.class, String.class); 827dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType, ourType); 837dd252788645e940eada959bdde927426e2531c9Paul Duffin } 847dd252788645e940eada959bdde927426e2531c9Paul Duffin 857dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_staticLocalClass() { 867dd252788645e940eada959bdde927426e2531c9Paul Duffin doTestNewParameterizedType_staticLocalClass(); 877dd252788645e940eada959bdde927426e2531c9Paul Duffin } 887dd252788645e940eada959bdde927426e2531c9Paul Duffin 897dd252788645e940eada959bdde927426e2531c9Paul Duffin private static void doTestNewParameterizedType_staticLocalClass() { 907dd252788645e940eada959bdde927426e2531c9Paul Duffin class LocalClass<T> {} 917dd252788645e940eada959bdde927426e2531c9Paul Duffin Type jvmType = new LocalClass<String>() {}.getClass().getGenericSuperclass(); 927dd252788645e940eada959bdde927426e2531c9Paul Duffin Type ourType = Types.newParameterizedType(LocalClass.class, String.class); 937dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType, ourType); 947dd252788645e940eada959bdde927426e2531c9Paul Duffin } 957dd252788645e940eada959bdde927426e2531c9Paul Duffin 967dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedTypeWithOwner() { 977dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType jvmType = (ParameterizedType) 987dd252788645e940eada959bdde927426e2531c9Paul Duffin new TypeCapture<Map.Entry<String, int[][]>>() {}.capture(); 997dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType ourType = Types.newParameterizedTypeWithOwner( 1007dd252788645e940eada959bdde927426e2531c9Paul Duffin Map.class, Map.Entry.class, String.class, int[][].class); 1017dd252788645e940eada959bdde927426e2531c9Paul Duffin 1027dd252788645e940eada959bdde927426e2531c9Paul Duffin new EqualsTester() 1037dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(jvmType, ourType) 1047dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(new TypeCapture<Map.Entry<String, String>>() {}.capture()) 1057dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(new TypeCapture<Map<String, Integer>>() {}.capture()) 1067dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 1077dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType.toString(), ourType.toString()); 1087dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(Map.class, ourType.getOwnerType()); 1097dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(Map.Entry.class, ourType.getRawType()); 1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ourType.getActualTypeArguments()) 1117dd252788645e940eada959bdde927426e2531c9Paul Duffin .iteratesOverSequence(jvmType.getActualTypeArguments()); 1127dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1137dd252788645e940eada959bdde927426e2531c9Paul Duffin 1147dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_serializable() { 1157dd252788645e940eada959bdde927426e2531c9Paul Duffin SerializableTester.reserializeAndAssert(Types.newParameterizedType( 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin Map.Entry.class, String.class, Integer.class)); 1177dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1187dd252788645e940eada959bdde927426e2531c9Paul Duffin 1197dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_ownerMismatch() { 1207dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 1217dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newParameterizedTypeWithOwner( 1227dd252788645e940eada959bdde927426e2531c9Paul Duffin Number.class, List.class, String.class); 1237dd252788645e940eada959bdde927426e2531c9Paul Duffin fail(); 1247dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (IllegalArgumentException expected) {} 1257dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1267dd252788645e940eada959bdde927426e2531c9Paul Duffin 1277dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_ownerMissing() { 1287dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals( 1297dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newParameterizedType(Map.Entry.class, String.class, Integer.class), 1307dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newParameterizedTypeWithOwner( 1317dd252788645e940eada959bdde927426e2531c9Paul Duffin null, Map.Entry.class, String.class, Integer.class)); 1327dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1337dd252788645e940eada959bdde927426e2531c9Paul Duffin 1347dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_invalidTypeParameters() { 1357dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 1367dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newParameterizedTypeWithOwner( 1377dd252788645e940eada959bdde927426e2531c9Paul Duffin Map.class, Map.Entry.class, String.class); 1387dd252788645e940eada959bdde927426e2531c9Paul Duffin fail(); 1397dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (IllegalArgumentException expected) {} 1407dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1417dd252788645e940eada959bdde927426e2531c9Paul Duffin 1427dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedType_primitiveTypeParameters() { 1437dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 1447dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newParameterizedTypeWithOwner( 1457dd252788645e940eada959bdde927426e2531c9Paul Duffin Map.class, Map.Entry.class, int.class, int.class); 1467dd252788645e940eada959bdde927426e2531c9Paul Duffin fail(); 1477dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (IllegalArgumentException expected) {} 1487dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1497dd252788645e940eada959bdde927426e2531c9Paul Duffin 1507dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewArrayType() { 1517dd252788645e940eada959bdde927426e2531c9Paul Duffin Type jvmType1 = new TypeCapture<List<String>[]>() {}.capture(); 1527dd252788645e940eada959bdde927426e2531c9Paul Duffin GenericArrayType ourType1 = (GenericArrayType) Types.newArrayType( 1537dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newParameterizedType(List.class, String.class)); 1547dd252788645e940eada959bdde927426e2531c9Paul Duffin Type jvmType2 = new TypeCapture<List[]>() {}.capture(); 1557dd252788645e940eada959bdde927426e2531c9Paul Duffin Type ourType2 = Types.newArrayType(List.class); 1567dd252788645e940eada959bdde927426e2531c9Paul Duffin new EqualsTester() 1577dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(jvmType1, ourType1) 1587dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(jvmType2, ourType2) 1597dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 1607dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(new TypeCapture<List<String>>() {}.capture(), 1617dd252788645e940eada959bdde927426e2531c9Paul Duffin ourType1.getGenericComponentType()); 1627dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType1.toString(), ourType1.toString()); 1637dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType2.toString(), ourType2.toString()); 1647dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1657dd252788645e940eada959bdde927426e2531c9Paul Duffin 1667dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewArrayTypeOfArray() { 1677dd252788645e940eada959bdde927426e2531c9Paul Duffin Type jvmType = new TypeCapture<int[][]>() {}.capture(); 1687dd252788645e940eada959bdde927426e2531c9Paul Duffin Type ourType = Types.newArrayType(int[].class); 1697dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType.toString(), ourType.toString()); 1707dd252788645e940eada959bdde927426e2531c9Paul Duffin new EqualsTester() 1717dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(jvmType, ourType) 1727dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 1737dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1747dd252788645e940eada959bdde927426e2531c9Paul Duffin 1757dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewArrayType_primitive() { 1767dd252788645e940eada959bdde927426e2531c9Paul Duffin Type jvmType = new TypeCapture<int[]>() {}.capture(); 1777dd252788645e940eada959bdde927426e2531c9Paul Duffin Type ourType = Types.newArrayType(int.class); 1787dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(jvmType.toString(), ourType.toString()); 1797dd252788645e940eada959bdde927426e2531c9Paul Duffin new EqualsTester() 1807dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(jvmType, ourType) 1817dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 1827dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1837dd252788645e940eada959bdde927426e2531c9Paul Duffin 1847dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewArrayType_upperBoundedWildcard() { 1857dd252788645e940eada959bdde927426e2531c9Paul Duffin Type wildcard = Types.subtypeOf(Number.class); 1867dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(Types.subtypeOf(Number[].class), Types.newArrayType(wildcard)); 1877dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1887dd252788645e940eada959bdde927426e2531c9Paul Duffin 1897dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewArrayType_lowerBoundedWildcard() { 1907dd252788645e940eada959bdde927426e2531c9Paul Duffin Type wildcard = Types.supertypeOf(Number.class); 1917dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(Types.supertypeOf(Number[].class), Types.newArrayType(wildcard)); 1927dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1937dd252788645e940eada959bdde927426e2531c9Paul Duffin 1947dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewArrayType_serializable() { 1957dd252788645e940eada959bdde927426e2531c9Paul Duffin SerializableTester.reserializeAndAssert( 1967dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newArrayType(int[].class)); 1977dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1987dd252788645e940eada959bdde927426e2531c9Paul Duffin 1997dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class WithWildcardType { 2007dd252788645e940eada959bdde927426e2531c9Paul Duffin 2017dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unused") 2027dd252788645e940eada959bdde927426e2531c9Paul Duffin void withoutBound(List<?> list) {} 2037dd252788645e940eada959bdde927426e2531c9Paul Duffin 2047dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unused") 2057dd252788645e940eada959bdde927426e2531c9Paul Duffin void withObjectBound(List<? extends Object> list) {} 2067dd252788645e940eada959bdde927426e2531c9Paul Duffin 2077dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unused") 2087dd252788645e940eada959bdde927426e2531c9Paul Duffin void withUpperBound(List<? extends int[][]> list) {} 2097dd252788645e940eada959bdde927426e2531c9Paul Duffin 2107dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unused") 2117dd252788645e940eada959bdde927426e2531c9Paul Duffin void withLowerBound(List<? super String[][]> list) {} 2127dd252788645e940eada959bdde927426e2531c9Paul Duffin 2137dd252788645e940eada959bdde927426e2531c9Paul Duffin static WildcardType getWildcardType(String methodName) throws Exception { 2147dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType parameterType = (ParameterizedType) 2157dd252788645e940eada959bdde927426e2531c9Paul Duffin WithWildcardType.class 2167dd252788645e940eada959bdde927426e2531c9Paul Duffin .getDeclaredMethod(methodName, List.class) 2177dd252788645e940eada959bdde927426e2531c9Paul Duffin .getGenericParameterTypes()[0]; 2187dd252788645e940eada959bdde927426e2531c9Paul Duffin return (WildcardType) parameterType.getActualTypeArguments()[0]; 2197dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2207dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2217dd252788645e940eada959bdde927426e2531c9Paul Duffin 2227dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewWildcardType() throws Exception { 2237dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType noBoundJvmType = 2247dd252788645e940eada959bdde927426e2531c9Paul Duffin WithWildcardType.getWildcardType("withoutBound"); 2257dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType objectBoundJvmType = 2267dd252788645e940eada959bdde927426e2531c9Paul Duffin WithWildcardType.getWildcardType("withObjectBound"); 2277dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType upperBoundJvmType = 2287dd252788645e940eada959bdde927426e2531c9Paul Duffin WithWildcardType.getWildcardType("withUpperBound"); 2297dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType lowerBoundJvmType = 2307dd252788645e940eada959bdde927426e2531c9Paul Duffin WithWildcardType.getWildcardType("withLowerBound"); 2317dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType objectBound = 2327dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.subtypeOf(Object.class); 2337dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType upperBound = 2347dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.subtypeOf(int[][].class); 2357dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType lowerBound = 2367dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.supertypeOf(String[][].class); 2377dd252788645e940eada959bdde927426e2531c9Paul Duffin 2387dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualWildcardType(noBoundJvmType, objectBound); 2397dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualWildcardType(objectBoundJvmType, objectBound); 2407dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualWildcardType(upperBoundJvmType, upperBound); 2417dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualWildcardType(lowerBoundJvmType, lowerBound); 2427dd252788645e940eada959bdde927426e2531c9Paul Duffin 2437dd252788645e940eada959bdde927426e2531c9Paul Duffin new EqualsTester() 2447dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup( 2457dd252788645e940eada959bdde927426e2531c9Paul Duffin noBoundJvmType, objectBoundJvmType, objectBound) 2467dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(upperBoundJvmType, upperBound) 2477dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(lowerBoundJvmType, lowerBound) 2487dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 2497dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2507dd252788645e940eada959bdde927426e2531c9Paul Duffin 2517dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewWildcardType_primitiveTypeBound() { 2527dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 2537dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.subtypeOf(int.class); 2547dd252788645e940eada959bdde927426e2531c9Paul Duffin fail(); 2557dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (IllegalArgumentException expected) {} 2567dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2577dd252788645e940eada959bdde927426e2531c9Paul Duffin 2587dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewWildcardType_serializable() { 2597dd252788645e940eada959bdde927426e2531c9Paul Duffin SerializableTester.reserializeAndAssert( 2607dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.supertypeOf(String.class)); 2617dd252788645e940eada959bdde927426e2531c9Paul Duffin SerializableTester.reserializeAndAssert( 2627dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.subtypeOf(String.class)); 2637dd252788645e940eada959bdde927426e2531c9Paul Duffin SerializableTester.reserializeAndAssert( 2647dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.subtypeOf(Object.class)); 2657dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2667dd252788645e940eada959bdde927426e2531c9Paul Duffin 2677dd252788645e940eada959bdde927426e2531c9Paul Duffin private static void assertEqualWildcardType( 2687dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType expected, WildcardType actual) { 2697dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(expected.toString(), actual.toString()); 2707dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(actual.toString(), expected.hashCode(), actual.hashCode()); 2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(actual.getLowerBounds()) 2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactlyAs(asList(expected.getLowerBounds())).inOrder(); 2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(actual.getUpperBounds()) 2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactlyAs(asList(expected.getUpperBounds())).inOrder(); 2757dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2767dd252788645e940eada959bdde927426e2531c9Paul Duffin 2777dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class WithTypeVariable { 2787dd252788645e940eada959bdde927426e2531c9Paul Duffin 2797dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unused") 2807dd252788645e940eada959bdde927426e2531c9Paul Duffin <T> void withoutBound(List<T> list) {} 2817dd252788645e940eada959bdde927426e2531c9Paul Duffin 2827dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unused") 2837dd252788645e940eada959bdde927426e2531c9Paul Duffin <T extends Object> void withObjectBound(List<T> list) {} 2847dd252788645e940eada959bdde927426e2531c9Paul Duffin 2857dd252788645e940eada959bdde927426e2531c9Paul Duffin @SuppressWarnings("unused") 2867dd252788645e940eada959bdde927426e2531c9Paul Duffin <T extends Number & CharSequence> void withUpperBound(List<T> list) {} 2877dd252788645e940eada959bdde927426e2531c9Paul Duffin 2887dd252788645e940eada959bdde927426e2531c9Paul Duffin static TypeVariable<?> getTypeVariable(String methodName) throws Exception { 2897dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType parameterType = (ParameterizedType) 2907dd252788645e940eada959bdde927426e2531c9Paul Duffin WithTypeVariable.class 2917dd252788645e940eada959bdde927426e2531c9Paul Duffin .getDeclaredMethod(methodName, List.class) 2927dd252788645e940eada959bdde927426e2531c9Paul Duffin .getGenericParameterTypes()[0]; 2937dd252788645e940eada959bdde927426e2531c9Paul Duffin return (TypeVariable<?>) parameterType.getActualTypeArguments()[0]; 2947dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2957dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2967dd252788645e940eada959bdde927426e2531c9Paul Duffin 2977dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewTypeVariable() throws Exception { 2987dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> noBoundJvmType = 2997dd252788645e940eada959bdde927426e2531c9Paul Duffin WithTypeVariable.getTypeVariable("withoutBound"); 3007dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> objectBoundJvmType = 3017dd252788645e940eada959bdde927426e2531c9Paul Duffin WithTypeVariable.getTypeVariable("withObjectBound"); 3027dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> upperBoundJvmType = 3037dd252788645e940eada959bdde927426e2531c9Paul Duffin WithTypeVariable.getTypeVariable("withUpperBound"); 3047dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> noBound = withBounds(noBoundJvmType); 3057dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> objectBound = withBounds(objectBoundJvmType, Object.class); 3067dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> upperBound = withBounds( 3077dd252788645e940eada959bdde927426e2531c9Paul Duffin upperBoundJvmType, Number.class, CharSequence.class); 3087dd252788645e940eada959bdde927426e2531c9Paul Duffin 3097dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualTypeVariable(noBoundJvmType, noBound); 3107dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualTypeVariable(noBoundJvmType, 3117dd252788645e940eada959bdde927426e2531c9Paul Duffin withBounds(noBoundJvmType, Object.class)); 3127dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualTypeVariable(objectBoundJvmType, objectBound); 3137dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEqualTypeVariable(upperBoundJvmType, upperBound); 3147dd252788645e940eada959bdde927426e2531c9Paul Duffin 3150888a09821a98ac0680fad765217302858e70fa4Paul Duffin new TypeVariableEqualsTester() 3167dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(noBoundJvmType, noBound) 3177dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(objectBoundJvmType, objectBound) 3180888a09821a98ac0680fad765217302858e70fa4Paul Duffin .addEqualityGroup(upperBoundJvmType, upperBound) 3197dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 3207dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3217dd252788645e940eada959bdde927426e2531c9Paul Duffin 3227dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewTypeVariable_primitiveTypeBound() { 3237dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 3240888a09821a98ac0680fad765217302858e70fa4Paul Duffin Types.newArtificialTypeVariable(List.class, "E", int.class); 3257dd252788645e940eada959bdde927426e2531c9Paul Duffin fail(); 3267dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (IllegalArgumentException expected) {} 3277dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3287dd252788645e940eada959bdde927426e2531c9Paul Duffin 3297dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewTypeVariable_serializable() throws Exception { 3307dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 3310888a09821a98ac0680fad765217302858e70fa4Paul Duffin SerializableTester.reserialize(Types.newArtificialTypeVariable(List.class, "E")); 3327dd252788645e940eada959bdde927426e2531c9Paul Duffin fail(); 3337dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (RuntimeException expected) {} 3347dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3357dd252788645e940eada959bdde927426e2531c9Paul Duffin 3367dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <D extends GenericDeclaration> TypeVariable<D> withBounds( 3377dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<D> typeVariable, Type... bounds) { 3380888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Types.newArtificialTypeVariable( 3397dd252788645e940eada959bdde927426e2531c9Paul Duffin typeVariable.getGenericDeclaration(), typeVariable.getName(), bounds); 3407dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3417dd252788645e940eada959bdde927426e2531c9Paul Duffin 3420888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class TypeVariableEqualsTester { 3430888a09821a98ac0680fad765217302858e70fa4Paul Duffin private final EqualsTester tester = new EqualsTester(); 3440888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3450888a09821a98ac0680fad765217302858e70fa4Paul Duffin TypeVariableEqualsTester addEqualityGroup(Type jvmType, Type... types) { 3460888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (Types.NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY) { 3470888a09821a98ac0680fad765217302858e70fa4Paul Duffin tester.addEqualityGroup(jvmType); 3480888a09821a98ac0680fad765217302858e70fa4Paul Duffin tester.addEqualityGroup((Object[]) types); 3490888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else { 3500888a09821a98ac0680fad765217302858e70fa4Paul Duffin tester.addEqualityGroup(Lists.asList(jvmType, types).toArray()); 3510888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3520888a09821a98ac0680fad765217302858e70fa4Paul Duffin return this; 3530888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3540888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3550888a09821a98ac0680fad765217302858e70fa4Paul Duffin void testEquals() { 3560888a09821a98ac0680fad765217302858e70fa4Paul Duffin tester.testEquals(); 3570888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3580888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3590888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3607dd252788645e940eada959bdde927426e2531c9Paul Duffin private static void assertEqualTypeVariable( 3617dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> expected, TypeVariable<?> actual) { 3627dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(expected.toString(), actual.toString()); 3637dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(expected.getName(), actual.getName()); 3647dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals( 3657dd252788645e940eada959bdde927426e2531c9Paul Duffin expected.getGenericDeclaration(), actual.getGenericDeclaration()); 3660888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (!Types.NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY) { 3670888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals(actual.toString(), expected.hashCode(), actual.hashCode()); 3680888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3690888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(actual.getBounds()).has().exactlyAs(asList(expected.getBounds())).inOrder(); 3707dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3717dd252788645e940eada959bdde927426e2531c9Paul Duffin 3727dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 3737dd252788645e940eada959bdde927426e2531c9Paul Duffin * Working with arrays requires defensive code. Verify that we clone the 3747dd252788645e940eada959bdde927426e2531c9Paul Duffin * type array for both input and output. 3757dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 3767dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedTypeImmutability() { 3777dd252788645e940eada959bdde927426e2531c9Paul Duffin Type[] typesIn = { String.class, Integer.class }; 3787dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType parameterizedType 3797dd252788645e940eada959bdde927426e2531c9Paul Duffin = Types.newParameterizedType(Map.class, typesIn); 3807dd252788645e940eada959bdde927426e2531c9Paul Duffin typesIn[0] = null; 3817dd252788645e940eada959bdde927426e2531c9Paul Duffin typesIn[1] = null; 3827dd252788645e940eada959bdde927426e2531c9Paul Duffin 3837dd252788645e940eada959bdde927426e2531c9Paul Duffin Type[] typesOut = parameterizedType.getActualTypeArguments(); 3847dd252788645e940eada959bdde927426e2531c9Paul Duffin typesOut[0] = null; 3857dd252788645e940eada959bdde927426e2531c9Paul Duffin typesOut[1] = null; 3867dd252788645e940eada959bdde927426e2531c9Paul Duffin 3877dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(String.class, parameterizedType.getActualTypeArguments()[0]); 3887dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(Integer.class, parameterizedType.getActualTypeArguments()[1]); 3897dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3907dd252788645e940eada959bdde927426e2531c9Paul Duffin 3917dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNewParameterizedTypeWithWrongNumberOfTypeArguments() { 3927dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 3937dd252788645e940eada959bdde927426e2531c9Paul Duffin Types.newParameterizedType( 3947dd252788645e940eada959bdde927426e2531c9Paul Duffin Map.class, String.class, Integer.class, Long.class); 3957dd252788645e940eada959bdde927426e2531c9Paul Duffin fail(); 3960888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (IllegalArgumentException expected) {} 3977dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3987dd252788645e940eada959bdde927426e2531c9Paul Duffin 3997dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testToString() { 4007dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(int[].class.getName(), Types.toString(int[].class)); 4017dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(int[][].class.getName(), Types.toString(int[][].class)); 4027dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(String[].class.getName(), Types.toString(String[].class)); 4037dd252788645e940eada959bdde927426e2531c9Paul Duffin Type elementType = List.class.getTypeParameters()[0]; 4047dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(elementType.toString(), Types.toString(elementType)); 4057dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4067dd252788645e940eada959bdde927426e2531c9Paul Duffin 4077dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNullPointers() { 4087dd252788645e940eada959bdde927426e2531c9Paul Duffin new NullPointerTester().testStaticMethods(Types.class, Visibility.PACKAGE); 4097dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4107dd252788645e940eada959bdde927426e2531c9Paul Duffin} 411