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 com.google.common.base.Preconditions.checkArgument; 207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull; 217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.Iterables.transform; 227dd252788645e940eada959bdde927426e2531c9Paul Duffin 237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.VisibleForTesting; 247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Function; 257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Joiner; 267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Objects; 277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Predicates; 287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableList; 297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Iterables; 307dd252788645e940eada959bdde927426e2531c9Paul Duffin 317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.Serializable; 327dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Array; 337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.GenericArrayType; 347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.GenericDeclaration; 357dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.ParameterizedType; 367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Type; 377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.TypeVariable; 387dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.WildcardType; 397dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Arrays; 407dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collection; 410888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.atomic.AtomicReference; 427dd252788645e940eada959bdde927426e2531c9Paul Duffin 437dd252788645e940eada959bdde927426e2531c9Paul Duffinimport javax.annotation.Nullable; 447dd252788645e940eada959bdde927426e2531c9Paul Duffin 457dd252788645e940eada959bdde927426e2531c9Paul Duffin/** 467dd252788645e940eada959bdde927426e2531c9Paul Duffin * Utilities for working with {@link Type}. 477dd252788645e940eada959bdde927426e2531c9Paul Duffin * 487dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Ben Yu 497dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 507dd252788645e940eada959bdde927426e2531c9Paul Duffinfinal class Types { 517dd252788645e940eada959bdde927426e2531c9Paul Duffin 527dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Class#toString without the "class " and "interface " prefixes */ 530888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final Function<Type, String> TYPE_TO_STRING = 540888a09821a98ac0680fad765217302858e70fa4Paul Duffin new Function<Type, String>() { 550888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String apply(Type from) { 560888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Types.toString(from); 570888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 580888a09821a98ac0680fad765217302858e70fa4Paul Duffin }; 597dd252788645e940eada959bdde927426e2531c9Paul Duffin 607dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final Joiner COMMA_JOINER = Joiner.on(", ").useForNull("null"); 617dd252788645e940eada959bdde927426e2531c9Paul Duffin 627dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns the array type of {@code componentType}. */ 637dd252788645e940eada959bdde927426e2531c9Paul Duffin static Type newArrayType(Type componentType) { 647dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType instanceof WildcardType) { 657dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType wildcard = (WildcardType) componentType; 667dd252788645e940eada959bdde927426e2531c9Paul Duffin Type[] lowerBounds = wildcard.getLowerBounds(); 677dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(lowerBounds.length <= 1, "Wildcard cannot have more than one lower bounds."); 687dd252788645e940eada959bdde927426e2531c9Paul Duffin if (lowerBounds.length == 1) { 697dd252788645e940eada959bdde927426e2531c9Paul Duffin return supertypeOf(newArrayType(lowerBounds[0])); 707dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 717dd252788645e940eada959bdde927426e2531c9Paul Duffin Type[] upperBounds = wildcard.getUpperBounds(); 727dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(upperBounds.length == 1, "Wildcard should have only one upper bound."); 737dd252788645e940eada959bdde927426e2531c9Paul Duffin return subtypeOf(newArrayType(upperBounds[0])); 747dd252788645e940eada959bdde927426e2531c9Paul Duffin } 757dd252788645e940eada959bdde927426e2531c9Paul Duffin } 767dd252788645e940eada959bdde927426e2531c9Paul Duffin return JavaVersion.CURRENT.newArrayType(componentType); 777dd252788645e940eada959bdde927426e2531c9Paul Duffin } 787dd252788645e940eada959bdde927426e2531c9Paul Duffin 797dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 807dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a type where {@code rawType} is parameterized by 817dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code arguments} and is owned by {@code ownerType}. 827dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 830888a09821a98ac0680fad765217302858e70fa4Paul Duffin static ParameterizedType newParameterizedTypeWithOwner( 840888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Nullable Type ownerType, Class<?> rawType, Type... arguments) { 857dd252788645e940eada959bdde927426e2531c9Paul Duffin if (ownerType == null) { 867dd252788645e940eada959bdde927426e2531c9Paul Duffin return newParameterizedType(rawType, arguments); 877dd252788645e940eada959bdde927426e2531c9Paul Duffin } 887dd252788645e940eada959bdde927426e2531c9Paul Duffin // ParameterizedTypeImpl constructor already checks, but we want to throw NPE before IAE 897dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(arguments); 907dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(rawType.getEnclosingClass() != null, "Owner type for unenclosed %s", rawType); 917dd252788645e940eada959bdde927426e2531c9Paul Duffin return new ParameterizedTypeImpl(ownerType, rawType, arguments); 927dd252788645e940eada959bdde927426e2531c9Paul Duffin } 937dd252788645e940eada959bdde927426e2531c9Paul Duffin 947dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 957dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a type where {@code rawType} is parameterized by 967dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code arguments}. 977dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 987dd252788645e940eada959bdde927426e2531c9Paul Duffin static ParameterizedType newParameterizedType(Class<?> rawType, Type... arguments) { 990888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new ParameterizedTypeImpl( 1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassOwnership.JVM_BEHAVIOR.getOwnerType(rawType), rawType, arguments); 1017dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1027dd252788645e940eada959bdde927426e2531c9Paul Duffin 1037dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Decides what owner type to use for constructing {@link ParameterizedType} from a raw class. */ 1047dd252788645e940eada959bdde927426e2531c9Paul Duffin private enum ClassOwnership { 1057dd252788645e940eada959bdde927426e2531c9Paul Duffin 1067dd252788645e940eada959bdde927426e2531c9Paul Duffin OWNED_BY_ENCLOSING_CLASS { 1077dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 1097dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> getOwnerType(Class<?> rawType) { 1107dd252788645e940eada959bdde927426e2531c9Paul Duffin return rawType.getEnclosingClass(); 1117dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1127dd252788645e940eada959bdde927426e2531c9Paul Duffin }, 1137dd252788645e940eada959bdde927426e2531c9Paul Duffin LOCAL_CLASS_HAS_NO_OWNER { 1147dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> getOwnerType(Class<?> rawType) { 1177dd252788645e940eada959bdde927426e2531c9Paul Duffin if (rawType.isLocalClass()) { 1187dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 1197dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 1207dd252788645e940eada959bdde927426e2531c9Paul Duffin return rawType.getEnclosingClass(); 1217dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1227dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1237dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 1247dd252788645e940eada959bdde927426e2531c9Paul Duffin 1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Nullable abstract Class<?> getOwnerType(Class<?> rawType); 1267dd252788645e940eada959bdde927426e2531c9Paul Duffin 1277dd252788645e940eada959bdde927426e2531c9Paul Duffin static final ClassOwnership JVM_BEHAVIOR = detectJvmBehavior(); 1287dd252788645e940eada959bdde927426e2531c9Paul Duffin 1297dd252788645e940eada959bdde927426e2531c9Paul Duffin private static ClassOwnership detectJvmBehavior() { 1307dd252788645e940eada959bdde927426e2531c9Paul Duffin class LocalClass<T> {} 1317dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> subclass = new LocalClass<String>() {}.getClass(); 1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin ParameterizedType parameterizedType = (ParameterizedType) 1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin subclass.getGenericSuperclass(); 1347dd252788645e940eada959bdde927426e2531c9Paul Duffin for (ClassOwnership behavior : ClassOwnership.values()) { 1357dd252788645e940eada959bdde927426e2531c9Paul Duffin if (behavior.getOwnerType(LocalClass.class) == parameterizedType.getOwnerType()) { 1367dd252788645e940eada959bdde927426e2531c9Paul Duffin return behavior; 1377dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1387dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1397dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new AssertionError(); 1407dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1417dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1427dd252788645e940eada959bdde927426e2531c9Paul Duffin 1437dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 1447dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a new {@link TypeVariable} that belongs to {@code declaration} with 1457dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code name} and {@code bounds}. 1467dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin static <D extends GenericDeclaration> TypeVariable<D> newArtificialTypeVariable( 1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin D declaration, String name, Type... bounds) { 1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new TypeVariableImpl<D>( 1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin declaration, 1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin name, 1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin (bounds.length == 0) 1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin ? new Type[] { Object.class } 1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin : bounds); 1557dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1567dd252788645e940eada959bdde927426e2531c9Paul Duffin 1577dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns a new {@link WildcardType} with {@code upperBound}. */ 1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin @VisibleForTesting static WildcardType subtypeOf(Type upperBound) { 1597dd252788645e940eada959bdde927426e2531c9Paul Duffin return new WildcardTypeImpl(new Type[0], new Type[] { upperBound }); 1607dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1617dd252788645e940eada959bdde927426e2531c9Paul Duffin 1627dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns a new {@link WildcardType} with {@code lowerBound}. */ 1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin @VisibleForTesting static WildcardType supertypeOf(Type lowerBound) { 1647dd252788645e940eada959bdde927426e2531c9Paul Duffin return new WildcardTypeImpl(new Type[] { lowerBound }, new Type[] { Object.class }); 1657dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1667dd252788645e940eada959bdde927426e2531c9Paul Duffin 1677dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 1687dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns human readable string representation of {@code type}. 1697dd252788645e940eada959bdde927426e2531c9Paul Duffin * <ul> 1707dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li> For array type {@code Foo[]}, {@code "com.mypackage.Foo[]"} are 1717dd252788645e940eada959bdde927426e2531c9Paul Duffin * returned. 1727dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li> For any class, {@code theClass.getName()} are returned. 1737dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li> For all other types, {@code type.toString()} are returned. 1747dd252788645e940eada959bdde927426e2531c9Paul Duffin * </ul> 1757dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 1767dd252788645e940eada959bdde927426e2531c9Paul Duffin static String toString(Type type) { 1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (type instanceof Class) 1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin ? ((Class<?>) type).getName() 1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin : type.toString(); 1807dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1817dd252788645e940eada959bdde927426e2531c9Paul Duffin 1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Nullable static Type getComponentType(Type type) { 1837dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(type); 1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin final AtomicReference<Type> result = new AtomicReference<Type>(); 1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin new TypeVisitor() { 1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override void visitTypeVariable(TypeVariable<?> t) { 1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin result.set(subtypeOfComponentType(t.getBounds())); 1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override void visitWildcardType(WildcardType t) { 1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin result.set(subtypeOfComponentType(t.getUpperBounds())); 1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override void visitGenericArrayType(GenericArrayType t) { 1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin result.set(t.getGenericComponentType()); 1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override void visitClass(Class<?> t) { 1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin result.set(t.getComponentType()); 1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin }.visit(type); 1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin return result.get(); 2007dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2017dd252788645e940eada959bdde927426e2531c9Paul Duffin 2027dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 2037dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns {@code ? extends X} if any of {@code bounds} is a subtype of {@code X[]}; or null 2047dd252788645e940eada959bdde927426e2531c9Paul Duffin * otherwise. 2057dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Nullable private static Type subtypeOfComponentType(Type[] bounds) { 2077dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type bound : bounds) { 2087dd252788645e940eada959bdde927426e2531c9Paul Duffin Type componentType = getComponentType(bound); 2097dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType != null) { 2107dd252788645e940eada959bdde927426e2531c9Paul Duffin // Only the first bound can be a class or array. 2117dd252788645e940eada959bdde927426e2531c9Paul Duffin // Bounds after the first can only be interfaces. 2127dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType instanceof Class) { 2137dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> componentClass = (Class<?>) componentType; 2147dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentClass.isPrimitive()) { 2157dd252788645e940eada959bdde927426e2531c9Paul Duffin return componentClass; 2167dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2177dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2187dd252788645e940eada959bdde927426e2531c9Paul Duffin return subtypeOf(componentType); 2197dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2207dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2217dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 2227dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2237dd252788645e940eada959bdde927426e2531c9Paul Duffin 2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final class GenericArrayTypeImpl 2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin implements GenericArrayType, Serializable { 2267dd252788645e940eada959bdde927426e2531c9Paul Duffin 2277dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Type componentType; 2287dd252788645e940eada959bdde927426e2531c9Paul Duffin 2297dd252788645e940eada959bdde927426e2531c9Paul Duffin GenericArrayTypeImpl(Type componentType) { 2307dd252788645e940eada959bdde927426e2531c9Paul Duffin this.componentType = JavaVersion.CURRENT.usedInGenericType(componentType); 2317dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2327dd252788645e940eada959bdde927426e2531c9Paul Duffin 2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Type getGenericComponentType() { 2347dd252788645e940eada959bdde927426e2531c9Paul Duffin return componentType; 2357dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2367dd252788645e940eada959bdde927426e2531c9Paul Duffin 2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String toString() { 2387dd252788645e940eada959bdde927426e2531c9Paul Duffin return Types.toString(componentType) + "[]"; 2397dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2407dd252788645e940eada959bdde927426e2531c9Paul Duffin 2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 2427dd252788645e940eada959bdde927426e2531c9Paul Duffin return componentType.hashCode(); 2437dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2447dd252788645e940eada959bdde927426e2531c9Paul Duffin 2450888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean equals(Object obj) { 2467dd252788645e940eada959bdde927426e2531c9Paul Duffin if (obj instanceof GenericArrayType) { 2477dd252788645e940eada959bdde927426e2531c9Paul Duffin GenericArrayType that = (GenericArrayType) obj; 2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Objects.equal( 2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin getGenericComponentType(), that.getGenericComponentType()); 2507dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2517dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 2527dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2537dd252788645e940eada959bdde927426e2531c9Paul Duffin 2547dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final long serialVersionUID = 0; 2557dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2567dd252788645e940eada959bdde927426e2531c9Paul Duffin 2570888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final class ParameterizedTypeImpl 2580888a09821a98ac0680fad765217302858e70fa4Paul Duffin implements ParameterizedType, Serializable { 2597dd252788645e940eada959bdde927426e2531c9Paul Duffin 2607dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Type ownerType; 2617dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> argumentsList; 2627dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Class<?> rawType; 2637dd252788645e940eada959bdde927426e2531c9Paul Duffin 2640888a09821a98ac0680fad765217302858e70fa4Paul Duffin ParameterizedTypeImpl( 2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Nullable Type ownerType, Class<?> rawType, Type[] typeArguments) { 2667dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(rawType); 2677dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(typeArguments.length == rawType.getTypeParameters().length); 2687dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(typeArguments, "type parameter"); 2697dd252788645e940eada959bdde927426e2531c9Paul Duffin this.ownerType = ownerType; 2707dd252788645e940eada959bdde927426e2531c9Paul Duffin this.rawType = rawType; 2717dd252788645e940eada959bdde927426e2531c9Paul Duffin this.argumentsList = JavaVersion.CURRENT.usedInGenericType(typeArguments); 2727dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2737dd252788645e940eada959bdde927426e2531c9Paul Duffin 2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Type[] getActualTypeArguments() { 2757dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(argumentsList); 2767dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2777dd252788645e940eada959bdde927426e2531c9Paul Duffin 2780888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Type getRawType() { 2797dd252788645e940eada959bdde927426e2531c9Paul Duffin return rawType; 2807dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2817dd252788645e940eada959bdde927426e2531c9Paul Duffin 2820888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Type getOwnerType() { 2837dd252788645e940eada959bdde927426e2531c9Paul Duffin return ownerType; 2847dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2857dd252788645e940eada959bdde927426e2531c9Paul Duffin 2860888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String toString() { 2877dd252788645e940eada959bdde927426e2531c9Paul Duffin StringBuilder builder = new StringBuilder(); 2887dd252788645e940eada959bdde927426e2531c9Paul Duffin if (ownerType != null) { 2897dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.append(Types.toString(ownerType)).append('.'); 2907dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2910888a09821a98ac0680fad765217302858e70fa4Paul Duffin builder.append(rawType.getName()) 2920888a09821a98ac0680fad765217302858e70fa4Paul Duffin .append('<') 2930888a09821a98ac0680fad765217302858e70fa4Paul Duffin .append(COMMA_JOINER.join(transform(argumentsList, TYPE_TO_STRING))) 2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin .append('>'); 2957dd252788645e940eada959bdde927426e2531c9Paul Duffin return builder.toString(); 2967dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2977dd252788645e940eada959bdde927426e2531c9Paul Duffin 2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (ownerType == null ? 0 : ownerType.hashCode()) 3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin ^ argumentsList.hashCode() ^ rawType.hashCode(); 3017dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3027dd252788645e940eada959bdde927426e2531c9Paul Duffin 3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean equals(Object other) { 3047dd252788645e940eada959bdde927426e2531c9Paul Duffin if (!(other instanceof ParameterizedType)) { 3057dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 3067dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3077dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType that = (ParameterizedType) other; 3087dd252788645e940eada959bdde927426e2531c9Paul Duffin return getRawType().equals(that.getRawType()) 3097dd252788645e940eada959bdde927426e2531c9Paul Duffin && Objects.equal(getOwnerType(), that.getOwnerType()) 3100888a09821a98ac0680fad765217302858e70fa4Paul Duffin && Arrays.equals( 3110888a09821a98ac0680fad765217302858e70fa4Paul Duffin getActualTypeArguments(), that.getActualTypeArguments()); 3127dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3137dd252788645e940eada959bdde927426e2531c9Paul Duffin 3147dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final long serialVersionUID = 0; 3157dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3167dd252788645e940eada959bdde927426e2531c9Paul Duffin 3170888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final class TypeVariableImpl<D extends GenericDeclaration> 3180888a09821a98ac0680fad765217302858e70fa4Paul Duffin implements TypeVariable<D> { 3197dd252788645e940eada959bdde927426e2531c9Paul Duffin 3207dd252788645e940eada959bdde927426e2531c9Paul Duffin private final D genericDeclaration; 3217dd252788645e940eada959bdde927426e2531c9Paul Duffin private final String name; 3227dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> bounds; 3237dd252788645e940eada959bdde927426e2531c9Paul Duffin 3247dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariableImpl(D genericDeclaration, String name, Type[] bounds) { 3257dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(bounds, "bound for type variable"); 3267dd252788645e940eada959bdde927426e2531c9Paul Duffin this.genericDeclaration = checkNotNull(genericDeclaration); 3277dd252788645e940eada959bdde927426e2531c9Paul Duffin this.name = checkNotNull(name); 3287dd252788645e940eada959bdde927426e2531c9Paul Duffin this.bounds = ImmutableList.copyOf(bounds); 3297dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3307dd252788645e940eada959bdde927426e2531c9Paul Duffin 3310888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Type[] getBounds() { 3327dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(bounds); 3337dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3347dd252788645e940eada959bdde927426e2531c9Paul Duffin 3350888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public D getGenericDeclaration() { 3367dd252788645e940eada959bdde927426e2531c9Paul Duffin return genericDeclaration; 3377dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3387dd252788645e940eada959bdde927426e2531c9Paul Duffin 3390888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String getName() { 3407dd252788645e940eada959bdde927426e2531c9Paul Duffin return name; 3417dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3427dd252788645e940eada959bdde927426e2531c9Paul Duffin 3430888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String toString() { 3447dd252788645e940eada959bdde927426e2531c9Paul Duffin return name; 3457dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3467dd252788645e940eada959bdde927426e2531c9Paul Duffin 3470888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 3487dd252788645e940eada959bdde927426e2531c9Paul Duffin return genericDeclaration.hashCode() ^ name.hashCode(); 3497dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3507dd252788645e940eada959bdde927426e2531c9Paul Duffin 3510888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean equals(Object obj) { 3520888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY) { 3530888a09821a98ac0680fad765217302858e70fa4Paul Duffin // equal only to our TypeVariable implementation with identical bounds 3540888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (obj instanceof TypeVariableImpl) { 3550888a09821a98ac0680fad765217302858e70fa4Paul Duffin TypeVariableImpl<?> that = (TypeVariableImpl<?>) obj; 3560888a09821a98ac0680fad765217302858e70fa4Paul Duffin return name.equals(that.getName()) 3570888a09821a98ac0680fad765217302858e70fa4Paul Duffin && genericDeclaration.equals(that.getGenericDeclaration()) 3580888a09821a98ac0680fad765217302858e70fa4Paul Duffin && bounds.equals(that.bounds); 3590888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3600888a09821a98ac0680fad765217302858e70fa4Paul Duffin return false; 3610888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else { 3620888a09821a98ac0680fad765217302858e70fa4Paul Duffin // equal to any TypeVariable implementation regardless of bounds 3630888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (obj instanceof TypeVariable) { 3640888a09821a98ac0680fad765217302858e70fa4Paul Duffin TypeVariable<?> that = (TypeVariable<?>) obj; 3650888a09821a98ac0680fad765217302858e70fa4Paul Duffin return name.equals(that.getName()) 3660888a09821a98ac0680fad765217302858e70fa4Paul Duffin && genericDeclaration.equals(that.getGenericDeclaration()); 3670888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3680888a09821a98ac0680fad765217302858e70fa4Paul Duffin return false; 3697dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3707dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3717dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3727dd252788645e940eada959bdde927426e2531c9Paul Duffin 3737dd252788645e940eada959bdde927426e2531c9Paul Duffin static final class WildcardTypeImpl implements WildcardType, Serializable { 3747dd252788645e940eada959bdde927426e2531c9Paul Duffin 3757dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> lowerBounds; 3767dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> upperBounds; 3777dd252788645e940eada959bdde927426e2531c9Paul Duffin 3787dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) { 3797dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(lowerBounds, "lower bound for wildcard"); 3807dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(upperBounds, "upper bound for wildcard"); 3817dd252788645e940eada959bdde927426e2531c9Paul Duffin this.lowerBounds = JavaVersion.CURRENT.usedInGenericType(lowerBounds); 3827dd252788645e940eada959bdde927426e2531c9Paul Duffin this.upperBounds = JavaVersion.CURRENT.usedInGenericType(upperBounds); 3837dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3847dd252788645e940eada959bdde927426e2531c9Paul Duffin 3850888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Type[] getLowerBounds() { 3867dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(lowerBounds); 3877dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3887dd252788645e940eada959bdde927426e2531c9Paul Duffin 3890888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Type[] getUpperBounds() { 3907dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(upperBounds); 3917dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3927dd252788645e940eada959bdde927426e2531c9Paul Duffin 3930888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean equals(Object obj) { 3947dd252788645e940eada959bdde927426e2531c9Paul Duffin if (obj instanceof WildcardType) { 3957dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType that = (WildcardType) obj; 3967dd252788645e940eada959bdde927426e2531c9Paul Duffin return lowerBounds.equals(Arrays.asList(that.getLowerBounds())) 3977dd252788645e940eada959bdde927426e2531c9Paul Duffin && upperBounds.equals(Arrays.asList(that.getUpperBounds())); 3987dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3997dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 4007dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4017dd252788645e940eada959bdde927426e2531c9Paul Duffin 4020888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 4037dd252788645e940eada959bdde927426e2531c9Paul Duffin return lowerBounds.hashCode() ^ upperBounds.hashCode(); 4047dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4057dd252788645e940eada959bdde927426e2531c9Paul Duffin 4060888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String toString() { 4077dd252788645e940eada959bdde927426e2531c9Paul Duffin StringBuilder builder = new StringBuilder("?"); 4087dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type lowerBound : lowerBounds) { 4097dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.append(" super ").append(Types.toString(lowerBound)); 4107dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4117dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type upperBound : filterUpperBounds(upperBounds)) { 4127dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.append(" extends ").append(Types.toString(upperBound)); 4137dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4147dd252788645e940eada959bdde927426e2531c9Paul Duffin return builder.toString(); 4157dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4167dd252788645e940eada959bdde927426e2531c9Paul Duffin 4177dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final long serialVersionUID = 0; 4187dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4197dd252788645e940eada959bdde927426e2531c9Paul Duffin 4207dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Type[] toArray(Collection<Type> types) { 4217dd252788645e940eada959bdde927426e2531c9Paul Duffin return types.toArray(new Type[types.size()]); 4227dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4237dd252788645e940eada959bdde927426e2531c9Paul Duffin 4247dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Iterable<Type> filterUpperBounds(Iterable<Type> bounds) { 4250888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Iterables.filter( 4260888a09821a98ac0680fad765217302858e70fa4Paul Duffin bounds, Predicates.not(Predicates.<Type>equalTo(Object.class))); 4277dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4287dd252788645e940eada959bdde927426e2531c9Paul Duffin 4297dd252788645e940eada959bdde927426e2531c9Paul Duffin private static void disallowPrimitiveType(Type[] types, String usedAs) { 4307dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type type : types) { 4317dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof Class) { 4327dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> cls = (Class<?>) type; 4330888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkArgument(!cls.isPrimitive(), 4340888a09821a98ac0680fad765217302858e70fa4Paul Duffin "Primitive type '%s' used as %s", cls, usedAs); 4357dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4367dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4377dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4387dd252788645e940eada959bdde927426e2531c9Paul Duffin 4397dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns the {@code Class} object of arrays with {@code componentType}. */ 4407dd252788645e940eada959bdde927426e2531c9Paul Duffin static Class<?> getArrayClass(Class<?> componentType) { 4417dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO(user): This is not the most efficient way to handle generic 4427dd252788645e940eada959bdde927426e2531c9Paul Duffin // arrays, but is there another way to extract the array class in a 4437dd252788645e940eada959bdde927426e2531c9Paul Duffin // non-hacky way (i.e. using String value class names- "[L...")? 4447dd252788645e940eada959bdde927426e2531c9Paul Duffin return Array.newInstance(componentType, 0).getClass(); 4457dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4467dd252788645e940eada959bdde927426e2531c9Paul Duffin 4477dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO(benyu): Once we are on Java 7, delete this abstraction 4487dd252788645e940eada959bdde927426e2531c9Paul Duffin enum JavaVersion { 4497dd252788645e940eada959bdde927426e2531c9Paul Duffin 4507dd252788645e940eada959bdde927426e2531c9Paul Duffin JAVA6 { 4510888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override GenericArrayType newArrayType(Type componentType) { 4527dd252788645e940eada959bdde927426e2531c9Paul Duffin return new GenericArrayTypeImpl(componentType); 4537dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4540888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override Type usedInGenericType(Type type) { 4557dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(type); 4567dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof Class) { 4577dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> cls = (Class<?>) type; 4587dd252788645e940eada959bdde927426e2531c9Paul Duffin if (cls.isArray()) { 4597dd252788645e940eada959bdde927426e2531c9Paul Duffin return new GenericArrayTypeImpl(cls.getComponentType()); 4607dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4617dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4627dd252788645e940eada959bdde927426e2531c9Paul Duffin return type; 4637dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4647dd252788645e940eada959bdde927426e2531c9Paul Duffin }, 4657dd252788645e940eada959bdde927426e2531c9Paul Duffin JAVA7 { 4660888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override Type newArrayType(Type componentType) { 4677dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType instanceof Class) { 4687dd252788645e940eada959bdde927426e2531c9Paul Duffin return getArrayClass((Class<?>) componentType); 4697dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 4707dd252788645e940eada959bdde927426e2531c9Paul Duffin return new GenericArrayTypeImpl(componentType); 4717dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4727dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4730888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override Type usedInGenericType(Type type) { 4747dd252788645e940eada959bdde927426e2531c9Paul Duffin return checkNotNull(type); 4757dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4760888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 4770888a09821a98ac0680fad765217302858e70fa4Paul Duffin ; 4787dd252788645e940eada959bdde927426e2531c9Paul Duffin 4790888a09821a98ac0680fad765217302858e70fa4Paul Duffin static final JavaVersion CURRENT = 4800888a09821a98ac0680fad765217302858e70fa4Paul Duffin (new TypeCapture<int[]>() {}.capture() instanceof Class) 4810888a09821a98ac0680fad765217302858e70fa4Paul Duffin ? JAVA7 : JAVA6; 4827dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract Type newArrayType(Type componentType); 4837dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract Type usedInGenericType(Type type); 4847dd252788645e940eada959bdde927426e2531c9Paul Duffin 4857dd252788645e940eada959bdde927426e2531c9Paul Duffin final ImmutableList<Type> usedInGenericType(Type[] types) { 4867dd252788645e940eada959bdde927426e2531c9Paul Duffin ImmutableList.Builder<Type> builder = ImmutableList.builder(); 4877dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type type : types) { 4887dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.add(usedInGenericType(type)); 4897dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4907dd252788645e940eada959bdde927426e2531c9Paul Duffin return builder.build(); 4917dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4927dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4937dd252788645e940eada959bdde927426e2531c9Paul Duffin 4940888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 4950888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Per https://code.google.com/p/guava-libraries/issues/detail?id=1635, 4960888a09821a98ac0680fad765217302858e70fa4Paul Duffin * In JDK 1.7.0_51-b13, TypeVariableImpl.equals() is changed to no longer be equal to custom 4970888a09821a98ac0680fad765217302858e70fa4Paul Duffin * TypeVariable implementations. As a result, we need to make sure our TypeVariable implementation 4980888a09821a98ac0680fad765217302858e70fa4Paul Duffin * respects symmetry. 4990888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Moreover, we don't want to reconstruct a native type variable <A> using our implementation 5000888a09821a98ac0680fad765217302858e70fa4Paul Duffin * unless some of its bounds have changed in resolution. This avoids creating unequal TypeVariable 5010888a09821a98ac0680fad765217302858e70fa4Paul Duffin * implementation unnecessarily. When the bounds do change, however, it's fine for the synthetic 5020888a09821a98ac0680fad765217302858e70fa4Paul Duffin * TypeVariable to be unequal to any native TypeVariable anyway. 5030888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 5040888a09821a98ac0680fad765217302858e70fa4Paul Duffin static final class NativeTypeVariableEquals<X> { 5050888a09821a98ac0680fad765217302858e70fa4Paul Duffin static final boolean NATIVE_TYPE_VARIABLE_ONLY = 5060888a09821a98ac0680fad765217302858e70fa4Paul Duffin !NativeTypeVariableEquals.class.getTypeParameters()[0].equals( 5070888a09821a98ac0680fad765217302858e70fa4Paul Duffin newArtificialTypeVariable(NativeTypeVariableEquals.class, "X")); 5080888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 5090888a09821a98ac0680fad765217302858e70fa4Paul Duffin 5107dd252788645e940eada959bdde927426e2531c9Paul Duffin private Types() {} 5117dd252788645e940eada959bdde927426e2531c9Paul Duffin} 512