/* * 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; import static com.alibaba.citrus.util.Assert.*; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.List; /** * 代表一个类型的信息。<code>TypeInfo</code>是和Java {@link Type}相对应的,但比Java Types更易用。 * <ul> * <li>{@link RawTypeInfo}和{@link Class}对应,但是不包括数组类型。</li> * <li>{@link ParameterizedTypeInfo}和{@link ParameterizedType}对应。</li> * <li>{@link TypeVariableInfo}和{@link TypeVariable}对应。</li> * <li>{@link WildcardTypeInfo}和{@link WildcardType}对应。</li> * <li>{@link ArrayTypeInfo}和{@link GenericArrayType}以及代表数组的{@link Class}对应。</li> * </ul> * * @author Michael Zhou */ public interface TypeInfo { /** 用来取得<code>TypeInfo</code>的工厂。 */ Factory factory = Factory.newFactory(); /** 类型{@link Object}的<code>TypeInfo</code>。 */ RawTypeInfo OBJECT = (RawTypeInfo) factory.getType(Object.class); /** 基本类型{@link boolean}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_BOOLEAN = (RawTypeInfo) factory.getType(boolean.class); /** 基本类型{@link byte}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_BYTE = (RawTypeInfo) factory.getType(byte.class); /** 基本类型{@link char}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_CHAR = (RawTypeInfo) factory.getType(char.class); /** 基本类型{@link double}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_DOUBLE = (RawTypeInfo) factory.getType(double.class); /** 基本类型{@link float}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_FLOAT = (RawTypeInfo) factory.getType(float.class); /** 基本类型{@link int}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_INT = (RawTypeInfo) factory.getType(int.class); /** 基本类型{@link long}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_LONG = (RawTypeInfo) factory.getType(long.class); /** 基本类型{@link short}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_SHORT = (RawTypeInfo) factory.getType(short.class); /** 基本类型{@link void}的<code>TypeInfo</code>。 */ RawTypeInfo PRIMITIVE_VOID = (RawTypeInfo) factory.getType(void.class); /** * 取得经过类型擦除(type erasure)之后的类型信息。 * <p> * <table border="1"> * <tr> * <th>TypeInfo</th> * <th>返回值</th> * <th>示例</th> * </tr> * <tr> * <td>{@link RawTypeInfo}</td> * <td>自身(<code>this</code>)</td> * <td><code>List</code> 将返回: <code>List</code></td> * </tr> * <tr> * <td>{@link ParameterizedTypeInfo}</td> * <td>raw类型</td> * <td><code>List<Integer></code> 将返回: <code>List</code></td> * </tr> * <tr> * <td>{@link TypeVariableInfo}</td> * <td>第一个upper bound类型</td> * <td><code><E></code> 将返回: <code>Object</code><br> * <code><E extends Number & Comparable></code> 将返回: * <code>Number</code></td> * </tr> * <tr> * <td>{@link WildcardTypeInfo}</td> * <td>第一个upper bound类型</td> * <td><code><?></code> 将返回: <code>Object</code><br> * <code><? extends Number></code> 将返回: <code>Number</code></td> * </tr> * <tr> * <td>{@link ArrayTypeInfo}</td> * <td>rawType的类名</td> * <td><code>List<Integer>[][]</code> 将返回:<code>List[][]</code></td> * </tr> * </table> * </p> */ Class<?> getRawType(); /** * 取得类型的名称。 * <p> * <table border="1"> * <tr> * <th>TypeInfo</th> * <th>返回值</th> * <th>示例</th> * </tr> * <tr> * <td>{@link RawTypeInfo}</td> * <td>类名</td> * <td><code>java.util.List</code> 将返回: <code>"java.util.List"</code></td> * </tr> * <tr> * <td>{@link ParameterizedTypeInfo}</td> * <td>rawType的类名</td> * <td><code>java.util.List<Integer></code> 将返回: * <code>"java.util.List"</code></td> * </tr> * <tr> * <td>{@link TypeVariableInfo}</td> * <td>变量名</td> * <td><code><E></code> 将返回: <code>"E"</code></td> * </tr> * <tr> * <td>{@link WildcardTypeInfo}</td> * <td>问号</td> * <td><code><? extends Object></code> 将返回: <code>"?"</code></td> * </tr> * <tr> * <td>{@link ArrayTypeInfo}</td> * <td>rawType的类名</td> * <td><code>java.util.List<Integer>[][]</code> 将返回: * <code>"[[Ljava.util.List;"</code></td> * </tr> * </table> * </p> */ String getName(); /** * 取得类型的简短名称。 * <p> * <table border="1"> * <tr> * <th>TypeInfo</th> * <th>返回值</th> * <th>示例</th> * </tr> * <tr> * <td>{@link RawTypeInfo}</td> * <td>类名</td> * <td><code>java.util.List</code> 将返回: <code>"List"</code></td> * </tr> * <tr> * <td>{@link ParameterizedTypeInfo}</td> * <td>rawType的类名</td> * <td><code>java.util.List<Integer></code> 将返回: <code>"List"</code></td> * </tr> * <tr> * <td>{@link TypeVariableInfo}</td> * <td>变量名</td> * <td><code><E></code> 将返回: <code>"E"</code></td> * </tr> * <tr> * <td>{@link WildcardTypeInfo}</td> * <td>问号</td> * <td><code><? extends Object></code> 将返回: <code>"?"</code></td> * </tr> * <tr> * <td>{@link ArrayTypeInfo}</td> * <td>rawType的类名</td> * <td><code>java.util.List<Integer>[][]</code> 将返回: * <code>"List[][]"</code></td> * </tr> * </table> * </p> */ String getSimpleName(); /** 判断当前类型是否为原子类型,例如:<code>int</code>、<code>boolean</code>等。 */ boolean isPrimitive(); /** * 是否为数组?只有两种类型的{@link TypeInfo}才有可能是数组: * <ol> * <li>{@link ArrayTypeInfo} - 例如:<code>int[]</code>, * <code>String[][]</code>, <code>List<Integer>[]</code>等。</li> * <li>{@link WildcardTypeInfo} - 例如:<code><? extends int[]></code>, * <code><? extends String[][]></code>, * <code><? extends List<Integer>[]></code>等。</li> * </ol> */ boolean isArray(); /** 判断当前类型是否为接口。 */ boolean isInterface(); /** * 假如当前{@link TypeInfo}是primtive类型(如<code>int</code>),则返回其包装类型(如 * <code>Integer</code>),否则返回<code>this</code>本身。 */ TypeInfo getPrimitiveWrapperType(); /** * 取得数组元素的类型。 * <p> * 对于多维数组,返回最终元素类型。例如:<code>int[][]</code>返回<code>int</code>。 * </p> * <p> * 如果不是数组,则返回本身<code>this</code>。 * </p> */ TypeInfo getComponentType(); /** * 取得直接的数组元素的类型。 * <p> * 对于多维数组,返回上一级元素类型。例如:<code>int[][]</code>返回<code>int[]</code>。 * </p> * <p> * 如果不是数组,则返回本身<code>this</code>。 * </p> */ TypeInfo getDirectComponentType(); /** 返回数组的维度,如果不是数组,则返回<code>0</code>。 */ int getDimension(); /** * 取得所有的接口,如果当前类是接口的话,包括当前类。 * * @see #getSupertypes() */ List<TypeInfo> getInterfaces(); /** * 取得所有的基类,从当前类向上推,如果当前类不是接口的话,包括当前类。 * * @see #getSupertypes() */ List<TypeInfo> getSuperclasses(); /** * 取得所有的基类和接口,从当前类向上推,包括当前类。 * <p> * 对于八个primitive类型和特殊类型<code>void</code>,它们没有任何父类。 * </p> * <p> * 如果一个类型,既不是接口,也不是数组,则按如下次序列出该类型的父类及接口。 例如对于 * <code>java.util.ArrayList</code>类型,将得到以下列表:(顺序为:本类、父类、父接口、Object类) * </p> * <ol> * <li>本类 - <code>java.util.ArrayList</code></li> * <li>父类 - <code>java.util.AbstractList</code></li> * <li>父类 - <code>java.util.AbstractCollection</code></li> * <li>父接口 - <code>java.util.List</code></li> * <li>父接口 - <code>java.util.Collection</code></li> * <li>父接口 - <code>java.util.RandomAccess</code></li> * <li>父接口 - <code>java.lang.Cloneable</code></li> * <li>父接口 - <code>java.io.Serializable</code></li> * <li>父接口 - <code>java.io.Iterable</code></li> * <li>Object类 - <code>java.lang.Object</code></li> * </ol> * <p> * 对于一个接口类型,则按如下次序列出该类的父接口。 例如对于<code>java.util.List</code> * 类型,将得到如下列表:(顺序为:本接口、父接口、Object类) * </p> * <ol> * <li>本接口 - <code>java.util.List</code></li> * <li>父接口 - <code>java.util.Collection</code></li> * <li>父接口 - <code>java.util.Iterable</code></li> * <li>Object类 - <code>java.lang.Object</code></li> * </ol> * <p> * 对于一个数组,此方法返回一个列表,列出所有component类型的父类和接口的维数相同的数组类型。 例如: * <code>java.util.ArrayList[][]</code> * 将取得以下列表:(顺序为:本数组、父类数组、父接口数组、Object类数组、父接口数组、Object类数组、数组父接口、Object类): * </p> * <ol> * <li>本数组 - <code>java.util.ArrayList[][]</code></li> * <li>父类数组 - <code>java.util.AbstractList[][]</code></li> * <li>父类数组 - <code>java.util.AbstractCollection[][]</code></li> * <li>父接口数组 - <code>java.util.List[][]</code></li> * <li>父接口数组 - <code>java.util.Collection[][]</code></li> * <li>父接口数组 - <code>java.util.RandomAccess[][]</code></li> * <li>父接口数组 - <code>java.lang.Cloneable[][]</code></li> * <li>父接口数组 - <code>java.io.Serializable[][]</code></li> * <li>父接口数组 - <code>java.io.Iterable[][]</code></li> * <li>Object类数组 - <code>java.lang.Object[][]</code></li> * <li>父接口数组 - <code>java.lang.Cloneable[]</code></li> * <li>父接口数组 - <code>java.io.Serializable[]</code></li> * <li>Object类数组 - <code>java.lang.Object[]</code></li> * <li>数组父接口 - <code>java.lang.Cloneable</code></li> * <li>数组父接口 - <code>java.io.Serializable</code></li> * <li>Object类 - <code>java.lang.Object</code></li> * </ol> * <p> * 原子类型的数组也是类似。例如:<code>int[][]</code>将得到以下列表: * </p> * <ol> * <li><code>int[][]</code></li> * <li><code>java.lang.Cloneable[]</code></li> * <li><code>java.io.Serializable[]</code></li> * <li><code>Object[]</code></li> * <li><code>java.lang.Cloneable</code></li> * <li><code>java.io.Serializable</code></li> * <li><code>java.lang.Object</code></li> * </ol> */ List<TypeInfo> getSupertypes(); /** * 在所有基类和接口中,查找rawClass为<code>equivalentClass</code>类型的{@link TypeInfo}。 * <p> * 例如, * <code>ArrayList<Integer>.getSupertype(List.class) => List<Integer></code> * </p> */ TypeInfo getSupertype(Class<?> equivalentClass); /** * 在指定上下文中分析实际类型。 * <p> * 相当于{@link resolve(context, true)}。 * </p> */ TypeInfo resolve(GenericDeclarationInfo context); /** * 在指定上下文中分析实际类型。 * <p> * 假如<code>context</code>为<code>List<E=Integer></code>,<br> * 那么解析<code>List<E></code>的结果为:<code>Integer</code>。 * </p> * <p> * 如果<code>includeBaseType==false</code>,那么解析类型变量时,将不会取得其baseType。 例如: * </p> * <p/> * <pre> * class MyClass<A> { * List<A> listA; * } * * interface Collection<E> extends Iterable<E> { * } * * interface Iterable<T> { * } * </pre> * <p> * 那么,<code>Iterable<T=E>.resolve(List<A>)</code>,将返回 * <code>Iterable<T=A></code>。 * </p> * <p> * 如果<code>includeBaseType==true</code>,那么,上述调用将返回 * <code>Iterable<T=Object></code>。 * </p> */ TypeInfo resolve(GenericDeclarationInfo context, boolean includeBaseType); /** 用来创建<code>TypeInfo</code>的工厂。 */ abstract class Factory { /** 取得指定{@link Type}对应的{@link TypeInfo}对象。 */ public abstract TypeInfo getType(Type type); /** * 取得指定非数组{@link Class}对应的{@link ClassTypeInfo}对象。 * <p> * 本方法不接受数组类,如果为数组,则抛出<code>IllegalArgumentException</code>。 * </p> * <p> * 本方法和{@link getType(Type)}是完全等同的,只是省去了一些cast而已。 * </p> * <p> * 由于{@link ClassTypeInfo}也是{@link GenericDeclarationInfo}的子类,<br> * 因此当参数为{@link Class}时,本方法的结果和{@link * getGenericDeclaration(GenericDeclaration)}也等同。 * </p> */ public final ClassTypeInfo getClassType(Class<?> type) { assertTrue(type != null && !type.isArray(), "type should not be array: %s", type.getName()); return (ClassTypeInfo) getType(type); } /** * 取得指定{@link ParameterizedType}对应的{@link ClassTypeInfo}对象。 * <p> * 本方法和{@link getType(Type)}是完全等同的,只是免去了一些cast而已。 * </p> */ public final ClassTypeInfo getClassType(ParameterizedType type) { return (ClassTypeInfo) getType(type); } /** 取得一组{@link TypeInfo}对象。 */ public abstract TypeInfo[] getTypes(Type[] types); /** * 取得指定{@link GenericDeclaration}对应的{@link GenericDeclarationInfo}对象。 * * <p> * 本方法不接受数组类,如果为数组,则抛出<code>IllegalArgumentException</code>。 * </p> */ public abstract GenericDeclarationInfo getGenericDeclaration(GenericDeclaration declaration); /** 创建一个参数化类型。 */ public abstract ParameterizedTypeInfo getParameterizedType(TypeInfo type, TypeInfo... args); /** 创建一个参数化类型。 */ public final ParameterizedTypeInfo getParameterizedType(TypeInfo type, Type... args) { return getParameterizedType(type, getTypes(args)); } /** 创建一个参数化类型。 */ public final ParameterizedTypeInfo getParameterizedType(Class<?> type, Type... args) { return getParameterizedType(getType(type), getTypes(args)); } /** 创建一个数组类型。 */ public abstract ArrayTypeInfo getArrayType(TypeInfo componentType, int dimension); /** 创建一个数组类型。 */ public final ArrayTypeInfo getArrayType(Class<?> componentType, int dimension) { return getArrayType(getType(componentType), dimension); } /** * 取得指定{@link Method}对应的{@link MethodInfo}对象。 * <p> * 本方法和{@link getGenericDeclaration(GenericDeclaration)} * 是完全等同的,只是免去了一些cast而已。 * </p> */ public final MethodInfo getMethod(Method method) { return (MethodInfo) getGenericDeclaration(method); } /** 以指定类型作为上下文,取得指定{@link Method}对应的{@link MethodInfo}对象。 */ public final MethodInfo getMethod(Method method, TypeInfo type) { MethodInfo result = getMethod(method); if (type != null) { Class<?> rawType = type.getRawType(); assertTrue(method.getDeclaringClass().isAssignableFrom(rawType), "method \"%s\" does not belong to type \"%s\"", method, type); if (type instanceof ClassTypeInfo) { result = result.resolve((ClassTypeInfo) type, false); } } return result; } /** * 取得指定{@link Constructor}对应的{@link MethodInfo}对象。 * <p> * 本方法和{@link getGenericDeclaration(GenericDeclaration)} * 是完全等同的,只是免去了一些cast而已。 * </p> */ public final MethodInfo getConstructor(Constructor<?> constructor) { return (MethodInfo) getGenericDeclaration(constructor); } /** 以指定类型作为上下文,取得指定{@link Constructor}对应的{@link MethodInfo}对象。 */ public final MethodInfo getConstructor(Constructor<?> constructor, TypeInfo type) { MethodInfo result = getConstructor(constructor); if (type != null) { Class<?> rawType = type.getRawType(); assertTrue(constructor.getDeclaringClass().equals(rawType), "constructor \"%s\" does not belong to type \"%s\"", constructor, type); if (type instanceof ClassTypeInfo) { result = result.resolve((ClassTypeInfo) type, false); } } return result; } /** 取得指定{@link Field}对应的{@link FieldInfo}对象。 */ public abstract FieldInfo getField(Field field); /** 以指定类型作为上下文,取得指定{@link Field}对应的{@link FieldInfo}对象。 */ public final FieldInfo getField(Field field, TypeInfo type) { FieldInfo result = getField(field); if (type != null) { Class<?> rawType = type.getRawType(); assertTrue(field.getDeclaringClass().isAssignableFrom(rawType), "field \"%s\" does not belong to type \"%s\"", field, type); if (type instanceof ClassTypeInfo) { result = result.resolve((ClassTypeInfo) type, false); } } return result; } /** 创建factory,但避免在compile时刻依赖impl package。 */ private static Factory newFactory() { String factoryImplName = Factory.class.getPackage().getName() + ".impl.TypeInfoFactory"; Factory factoryImpl = null; try { factoryImpl = (Factory) Factory.class.getClassLoader().loadClass(factoryImplName).newInstance(); } catch (Exception e) { unexpectedException(e, "Failed to create TypeInfo.Factory"); } return factoryImpl; } } }