/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.citrus.generictype.impl; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.ClassUtil.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static java.util.Collections.*; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Collections; import java.util.List; import com.alibaba.citrus.generictype.ClassTypeInfo; import com.alibaba.citrus.generictype.FieldInfo; import com.alibaba.citrus.generictype.GenericDeclarationInfo; import com.alibaba.citrus.generictype.MethodInfo; import com.alibaba.citrus.generictype.ParameterizedTypeInfo; import com.alibaba.citrus.generictype.RawTypeInfo; import com.alibaba.citrus.generictype.TypeInfo; import com.alibaba.citrus.generictype.TypeVariableInfo; import com.alibaba.citrus.util.internal.LazyLoader; import com.alibaba.citrus.util.internal.LazyLoader.Loader; /** * 对{@link ParameterizedTypeInfo}的实现。 * * @author Michael Zhou */ class ParameterizedTypeImpl implements ParameterizedTypeInfo { private final RawTypeInfo rawType; private final LazyLoader<Supertypes, Object> supertypesLoader; private List<TypeInfo> actualTypeArguments; private boolean resolved; ParameterizedTypeImpl(RawTypeInfo rawType) { assertTrue(rawType != null && getTypeParameters(rawType).length > 0, "rawType"); this.rawType = rawType; this.supertypesLoader = LazyLoader.getDefault(new SupertypesLoader()); } void init(TypeInfo[] actualTypeArguments) { this.actualTypeArguments = unmodifiableList(asList(actualTypeArguments)); // 检查参数个数是否匹配 int actualArgs = this.actualTypeArguments.size(); int expectedParams = getTypeParameters(rawType).length; assertTrue(actualArgs == expectedParams, "actual arguments length not match: expected %d, actual %d", expectedParams, actualArgs); // 检查参数类型是否匹配 for (int i = 0; i < actualTypeArguments.length; i++) { TypeVariable<?> var = getTypeParameters(rawType)[i]; Class<?> argClass = actualTypeArguments[i].getRawType(); checkBounds(var, null, argClass, false); } } private static TypeVariable<?>[] getTypeParameters(RawTypeInfo rawType) { return rawType.getRawType().getTypeParameters(); // 避免调用rawType.getTypeParameters()以免递归 } /** 检查类型<code>argClass</code>是不是<code>var</code>的bounds的子类。 */ private static void checkBounds(TypeVariable<?> var, Type type, Class<?> argClass, boolean array) { if (type == null) { type = var; } if (type instanceof Class<?>) { Class<?> superclass = (Class<?>) type; assertTrue(superclass.isAssignableFrom(argClass), array ? "actual argument of parameter %s should be array of sub-class of %s, but was array of %s" : "actual argument of parameter %s should be sub-class of %s, but was %s", var, superclass, argClass); return; } if (type instanceof TypeVariable<?>) { for (Type ub : ((TypeVariable<?>) type).getBounds()) { checkBounds(var, ub, argClass, false); } return; } if (type instanceof GenericArrayType) { assertTrue(argClass.isArray(), "actual argument of parameter %s should be array, but was %s", var, argClass); checkBounds(var, ((GenericArrayType) type).getGenericComponentType(), argClass.getComponentType(), true); return; } if (type instanceof ParameterizedType) { checkBounds(var, ((ParameterizedType) type).getRawType(), argClass, false); return; } } public Class<?> getRawType() { return rawType.getRawType(); } public String getName() { return rawType.getName(); } public String getSimpleName() { return rawType.getSimpleName(); } public boolean isPrimitive() { return false; } public boolean isArray() { return false; } public boolean isInterface() { return rawType.isInterface(); } public TypeInfo getPrimitiveWrapperType() { return this; } public TypeInfo getComponentType() { return this; } public TypeInfo getDirectComponentType() { return this; } public int getDimension() { return 0; } public boolean isGeneric() { return true; } public List<TypeVariableInfo> getTypeParameters() { return rawType.getTypeParameters(); } public List<TypeInfo> getInterfaces() { return supertypesLoader.getInstance().interfaces; } public List<TypeInfo> getSuperclasses() { return supertypesLoader.getInstance().superclasses; } public List<TypeInfo> getSupertypes() { return supertypesLoader.getInstance().supertypes; } public TypeInfo getSupertype(Class<?> equivalentClass) { return TypeInfoFactory.findSupertype(this, equivalentClass); } // Implementation of TypeInfo.resolve public ClassTypeInfo resolve(GenericDeclarationInfo context) { return resolve(context, true); } // Implementation of TypeInfo.resolve public ClassTypeInfo resolve(GenericDeclarationInfo context, boolean includeBaseType) { if (resolved) { return this; } else { List<TypeVariableInfo> vars = getTypeParameters(); List<TypeInfo> actualArgs = getActualTypeArguments(); TypeInfo[] resolvedArgs = new TypeInfo[vars.size()]; boolean resolved = true; boolean changed = false; for (int i = 0; i < resolvedArgs.length; i++) { TypeInfo arg = actualArgs.get(i); TypeInfo resolvedArg = arg.resolve(context, includeBaseType); if (arg != resolvedArg) { changed = true; } // 优化:如果resolved,以后就不必重新resolved。 if (resolvedArg instanceof ParameterizedTypeImpl) { resolved &= ((ParameterizedTypeImpl) resolvedArg).resolved; } else if (resolvedArg instanceof TypeVariableInfo) { resolved = false; } resolvedArgs[i] = resolvedArg; } ParameterizedTypeImpl result = changed ? (ParameterizedTypeImpl) factory.getParameterizedType(rawType, resolvedArgs) : this; if (resolved) { result.resolved = resolved; } return result; } } public List<TypeInfo> getActualTypeArguments() { return actualTypeArguments; } public TypeInfo getActualTypeArgument(String name) { List<TypeVariableInfo> vars = getTypeParameters(); for (int i = 0; i < vars.size(); i++) { if (vars.get(i).getName().equals(name)) { return actualTypeArguments.get(i); } } return null; } // Implementation of ClassTypeInfo public FieldInfo getField(String name) { return TypeInfoFactory.getField(this, this, name); } // Implementation of ClassTypeInfo public FieldInfo getField(ClassTypeInfo declaringType, String name) { return TypeInfoFactory.getField(this, declaringType, name); } // Implementation of ClassTypeInfo public MethodInfo getConstructor(Class<?>... paramTypes) { return TypeInfoFactory.getConstructor(this, paramTypes); } // Implementation of ClassTypeInfo public MethodInfo getMethod(String methodName, Class<?>... paramTypes) { return TypeInfoFactory.getMethod(this, methodName, paramTypes); } /** 取得hash值。 */ @Override public int hashCode() { return getClass().hashCode() ^ rawType.hashCode() ^ actualTypeArguments.hashCode(); } /** 判断两个对象是否相同。 */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (other == null || !other.getClass().equals(getClass())) { return false; } ParameterizedTypeImpl otherType = (ParameterizedTypeImpl) other; return rawType.equals(otherType.rawType) && actualTypeArguments.equals(otherType.actualTypeArguments); } /** 取得字符串表示。 */ @Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append(getSimpleClassName(getRawType())); buf.append("<"); for (int i = 0; i < actualTypeArguments.size(); i++) { buf.append(rawType.getTypeParameters().get(i)).append("=").append(actualTypeArguments.get(i)); if (i < actualTypeArguments.size() - 1) { buf.append(", "); } } buf.append(">"); return buf.toString(); } /** 父类、接口的信息。 */ private static class Supertypes { private final List<TypeInfo> supertypes; private final List<TypeInfo> interfaces; private final List<TypeInfo> superclasses; private Supertypes(ParameterizedTypeImpl parameterizedType) { RawTypeInfo rawType = parameterizedType.rawType; List<TypeInfo> rawSupertypes = rawType.getSupertypes(); List<TypeInfo> rawInterfaces = rawType.getInterfaces(); List<TypeInfo> rawSuperclasses = rawType.getSuperclasses(); List<TypeInfo> supertypes = createArrayList(rawSupertypes.size()); List<TypeInfo> interfaces = createArrayList(rawInterfaces.size()); List<TypeInfo> superclasses = createArrayList(rawSuperclasses.size()); for (TypeInfo supertype : rawSupertypes) { if (supertype instanceof RawTypeInfo) { if (supertype == rawType) { supertypes.add(parameterizedType); // supertype的第一个就是自己( // 类或接口) } else { supertypes.add(supertype); } } else if (supertype instanceof ParameterizedTypeInfo) { supertypes.add(supertype); } else { unreachableCode("Unexpected super type: %s", supertype); } } // 创建lists for (TypeInfo supertype : supertypes) { if (supertype.getRawType().isInterface()) { interfaces.add(supertype); } else { superclasses.add(supertype); } } assertTrue(supertypes.size() == rawSupertypes.size(), "supertypes size"); assertTrue(interfaces.size() == rawInterfaces.size(), "interfaces size"); assertTrue(superclasses.size() == rawSuperclasses.size(), "superclasses size"); this.supertypes = Collections.unmodifiableList(supertypes); this.interfaces = Collections.unmodifiableList(interfaces); this.superclasses = Collections.unmodifiableList(superclasses); } } /** 创建supertypes的装载器。 */ private class SupertypesLoader implements Loader<Supertypes, Object> { public Supertypes load(Object context) { return new Supertypes(ParameterizedTypeImpl.this); } } }