Type接口:Java中的类型
跳到导航
跳到搜索
关于
Type 是 Java 编程语言中所有类型的公共高级接口,也就是 Java 中所有类型的“父类”(也是 Class 类的父类)。
Type 体系中的类型包括:
- 原始类型(Class):不仅仅包含我们平常所指的类,还包括枚举、数组、注解等。
- 参数化类型(ParameterizedType):即,平常所用到的泛型 List<>、Map<>。
- 数组类型(GenericArrayType):特指,带有泛型、参数化类型的数组(如,T[]) 。
- 注意,并非常用的类型数组(如,String[] 、byte[]);
- 基本类型(Class),即,Java 的基本类型(byte、short、int、long、float、double、char)。
Type 接口[1]
Type 是个空接口,没有定义任何方法,通过多态提高了程序的扩展性。
位于:“java.lang.reflect”包
Type接口:
package java.lang.reflect; public interface Type { default String getTypeName() { return toString(); } }
Type 相关的子接口和子接口实现类:
- ParameterizedType[2]:参数化类型。
- 如:“List<T>”、“Map<String, Integer>”
- 实现类:ParameterizedTypeImpl
- GenericArrayType[2]:“参数化类型”/“类型变量”的数组类型。
- 如:“T[]”、“List<String>[]”
- 实现类:GenericArrayTypeImpl
- TypeVariable[2]:类型变量。 ——【泛型声明时所用的变量,即为“类型变量”】
- 如:“T”、“List<T>”中的“T” ——【TypeVariable 只表示“类型变量”本身,区别于“参数化类型”】
- 实现类:TypeVariableImpl
- WildcardType[2]:泛型表达式(通配符表达式)。
- 如:“List<? extends Number>”、“List<? super String>”
- 实现类:WildcardTypeImpl
- Class:原始类型。
- 以上几种 Type 以外(即,普通的对象)就是一个 Class 类型,是 Type 中的一种。
子接口和实现类,位于:“java.lang.reflect” 子接口的实现类,位于:“sun.reflect.generics.reflectiveObjects”
【子接口】ParameterizedType
package java.lang.reflect; /** * ParameterizedType 表示一个“参数化的类型”,如“Collection<String>” * * 1、参数化类型是在反射方法首次需要时创建的,如此包中指定。 * 2、创建参数化类型 p 时,解析 p 实例化的泛型类型声明,并递归创建 p 的所有“类型参数”(TypeVariable)。 * 3、重复创建参数化类型无效。 * * 实现此接口的类的实例必须实现 equals() 方法: * 该方法将“共享相同泛型类型声明,并具有相等类型参数”的任意两个实例等效。 * * @since 1.5 */ public interface ParameterizedType extends Type { /** * 返回【表示“此类型的实际类型参数”的{@code Type}对象数组】 * ————【即,获取“<>”中的实际类型】 * * * 注意,在某些情况下,返回的数组为空。 * 如果此类型表示嵌套在参数化类型中的非参数化类型,则可能发生这种情况。 */ Type[] getActualTypeArguments(); /** * 返回【表示“声明此类型的类或接口”的{@code Type}对象】 * ————【即,获取“<>”前的实际类型】 */ Type getRawType(); /** * 返回【表示“此类型所属类型”的{@code Type}对象】 * ————【即,获取该类型(为内部类)的外部类的类型】 * * 注意,如果此类型是顶级类型,则返回{@code null}。 */ Type getOwnerType(); }
【子接口】GenericArrayType
package java.lang.reflect; /** * GenericArrayType 表示其组件类型为“参数化类型”(ParameterizedType)或“类型变量”(TypeVariable)的数组类型。 * * @since 1.5 */ public interface GenericArrayType extends Type { /** * 返回【表示“此数组的组件类型”的{@code Type}对象】 * ————【即,获取数组元素的实际类型】 */ Type getGenericComponentType(); }
【子接口】TypeVariable
package java.lang.reflect; /** * TypeVariable 是各种“类型变量”的通用超级接口。 * * 1、类型变量是在反射方法第一次需要时创建的,如此包中所指定的。 * 2、如果类型变量 t 被类型(即类、接口或注释类型)T 引用, * 并且 T 由 T 的第 n 个封闭类声明, * 则创建 t 需要解析 T 的第 i 个封闭类,其中 i=0 到 n(含)。 * 3、创建类型变量不能导致创建其边界。 * 4、重复创建类型变量无效。 * * @since 1.5 */ public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement { /** * 返回【表示“此‘类型变量’上限”的{@code Type}对象数组】 * ————【即,获取该“类型变量”的上限】 * * 注意,如果没有显式声明上限,则上限为{@code Object}。 */ Type[] getBounds(); /** * 返回【表示“此‘类型变量’声明的泛型声明”的{@code GenericDeclaration}对象】 * ————【即,获取声明该“类型变量”的实体(类、方法、构造器)】 */ D getGenericDeclaration(); /** * 返回【源代码中出现的此‘类型变量’的名称】 */ String getName(); /** * 返回一个 AnnotatedType 对象的数组,用于表示此 TypeVariable 表示的类型参数的上限。 * 数组中对象的顺序与类型参数声明中边界的顺序相对应。 * * 注意,如果类型参数声明无边界,则返回长度为 0 的数组。 */ AnnotatedType[] getAnnotatedBounds(); }
【子接口】WildcardType
package java.lang.reflect; /** * WildcardType 表示通配符类型表达式。 * 例如{@code ?}、{@code ? extends Number}或{@ccode ? super Integer}。 * * @since 1.5 */ public interface WildcardType extends Type { /** * 返回【表示此类型变量上限的{@code Type}对象数组】 * ————【即,获取通配符“extends”的类型】 */ Type[] getUpperBounds(); /** * 返回【表示此类型变量下限的{@code Type}对象数组】 * ————【即,获取通配符“super”的类型】 */ Type[] getLowerBounds(); }
【实现类】Class
在 Java 中,每个“.class”文件在程序运行期间,都对应着一个 Class 对象,这个对象保存有这个类的全部信息。
因此,Class 对象也称之为【Java 反射的基础】;
Type(子接口、实现类)示例[3]
示例:ParameterizedType
package com.eijux.springdemo1; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; public class ParameterizedTypeDemo<T> { private List<T> list = null; private Map<String, Integer> map = null; private Map.Entry<String, Integer> mapEntry; public static void testParameterizedType() throws NoSuchFieldException { /** fieldList 变量: * 类型:Field * 值:"com.eijux.springdemo1.ParameterizedTypeDemo.list" */ Field fieldList = ParameterizedTypeDemo.class.getDeclaredField("list"); /** * Field.getGenericType(): 获取【表示“Field 的类型”的 Type】 * 返回一个 {@code Type} 对象,该对象表示此 {@code Field} 对象所表示的字段的声明类型。 * * typeList 变量: * 类型:Type * 实际类型:ParameterizedTypeImpl(ParameterizedType 的实现类) * 使用时可能需要强制类型转换 * 值:"java.util.List<T>" */ Type typeList = fieldList.getGenericType(); /** * Object.getClass(): 返回此 {@code Object} 的【运行时类型(实际类型)】。 * 返回的 {@code Class} 对象是由所表示类的 {@code 静态同步} 方法锁定的对象。 * * Type.getTypeName(): 返回描述此类型的字符串,包括有关任何类型参数的信息。 */ System.out.println(typeList.getClass().getName()); // sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl System.out.println(typeList.getTypeName().toString()); // java.util.List<T> } public static void testGetActualTypeArguments() throws NoSuchFieldException { Field fieldMap = ParameterizedTypeDemo.class.getDeclaredField("map"); // 强制类型转换:Type -> ParameterizedType(实际使用其实现类 ParameterizedTypeImpl) ParameterizedType parameterizedTypeMap = (ParameterizedType) fieldMap.getGenericType(); /** * ParameterizedType.getActualTypeArguments(): 获取【表示“泛型的实际类型”的 Type】 * 可能会存在多个泛型,例如 Map<K,V>,会返回 Type[]; */ Type[] types = parameterizedTypeMap.getActualTypeArguments(); System.out.println(types[0]); // class java.lang.String System.out.println(types[1]); // class java.lang.Integer } public static void testGetRawType() throws NoSuchFieldException { Field fieldMap = ParameterizedTypeDemo.class.getDeclaredField("map"); // 强制类型转换:Type -> ParameterizedType(实际使用其实现类 ParameterizedTypeImpl) ParameterizedType parameterizedTypeMap = (ParameterizedType) fieldMap.getGenericType(); /** * ParameterizedType.getRawType(): 获取【表示“声明泛型的类或者接口”的 Type】 * 即,泛型声明的“<>”前面的那个值,例如 Map<K,V> 将返回“表示 Map 的 Type” */ Type type = parameterizedTypeMap.getRawType(); System.out.println(type); // interface java.util.Map } public static void testGetOwnerType() throws NoSuchFieldException { Field fieldMapEntry = ParameterizedTypeDemo.class.getDeclaredField("mapEntry"); // 强制类型转换:Type -> ParameterizedType(实际使用其实现类 ParameterizedTypeImpl) ParameterizedType parameterizedTypeMapEntry = (ParameterizedType) fieldMapEntry.getGenericType(); /** * ParameterizedType.getOwnerType(): 获取【表示“泛型的拥有者”的 Type】 * 即,若该泛型为某类的内部类,则可以获取该泛型的父类的 Type * 例如,Map.Entry<String, Integer> 将返回“表示 Map 的 Type” */ Type type = parameterizedTypeMapEntry.getOwnerType(); System.out.println(type); // interface java.util.Map } public static void main(String[] agrs) throws NoSuchFieldException { testParameterizedType(); testGetActualTypeArguments(); testGetRawType(); testGetOwnerType(); } }
示例:GenericArrayType
package com.eijux.springdemo1; import java.lang.reflect.Field; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Type; import java.util.List; public class GenericArrayTypeDemo<T> { private T[] t; private List<String>[] listArray; public static void testGenericArrayType() throws NoSuchFieldException { /** fieldT 变量: * 类型:Field * 值:"com.eijux.springdemo1.GenericArrayTypeDemo.t" */ Field fieldT = GenericArrayTypeDemo.class.getDeclaredField("t"); /** * Field.getGenericType(): 获取【表示“Field 的类型”的 Type】 * 返回一个 {@code Type} 对象,该对象表示此 {@code Field} 对象所表示的字段的声明类型。 * * typeList 变量: * 类型:Type * 实际类型:GenericArrayTypeImpl(GenericArrayType 的实现类) * 使用时可能需要强制类型转换 * 值:"T[]" */ Type typeList = fieldT.getGenericType(); /** * Object.getClass(): 返回此 {@code Object} 的【运行时类型(实际类型)】。 * 返回的 {@code Class} 对象是由所表示类的 {@code 静态同步} 方法锁定的对象。 * * Type.getTypeName(): 返回描述此类型的字符串,包括有关任何类型参数的信息。 */ System.out.println(typeList.getClass().getName()); // sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl System.out.println(typeList.getTypeName().toString()); // T[] } public static void testGetGenericComponentType() throws NoSuchFieldException { Field fieldListArray = GenericArrayTypeDemo.class.getDeclaredField("listArray"); // 强制类型转换:Type -> GenericArrayType(实际使用其实现类 GenericArrayTypeImpl) GenericArrayType genericArrayType = (GenericArrayType) fieldListArray.getGenericType(); /** * GenericArrayType.getGenericComponentType(): 获取【表示“泛型数组的元素”的 Type】 * 无论是几维数组,getGenericComponentType()方法都只会脱去最右边的[] */ Type type = genericArrayType.getGenericComponentType(); System.out.println(type); // java.util.List<java.lang.String> } public static void main(String[] args) throws NoSuchFieldException { testGenericArrayType(); testGetGenericComponentType(); } }
示例:TypeVariable
package com.eijux.springdemo1; import java.io.Serializable; import java.lang.reflect.*; import java.util.List; public class TypeVariableDemo<T extends Number & Serializable & Comparable> { private T t; private List<T> list; public static void testTypeVariable() throws NoSuchFieldException { /** fieldList 变量: * 类型:Field * 值:"com.eijux.springdemo1.TypeVariableDemo.list" */ Field fieldList = TypeVariableDemo.class.getDeclaredField("list"); /** * Field.getGenericType(): 获取【表示“Field 的类型”的 Type】 * 返回一个 {@code Type} 对象,该对象表示此 {@code Field} 对象所表示的字段的声明类型。 * * typeList 变量: * 类型:Type * 实际类型:ParameterizedTypeImpl(ParameterizedType 的实现类) * 使用时可能需要强制类型转换 * 值:"java.util.List<T>" */ Type typeList = fieldList.getGenericType(); /** * ParameterizedType.getActualTypeArguments(): 获取【表示“泛型的实际类型”的 Type】 * 可能会存在多个泛型,例如 Map<K,V>,会返回 Type[]; */ Type[] type = ((ParameterizedType) typeList).getActualTypeArguments(); System.out.println(type[0].getClass()); // class sun.reflect.generics.reflectiveObjects.TypeVariableImpl } public static void testGetBounds() throws NoSuchFieldException { Field fieldT = TypeVariableDemo.class.getDeclaredField("t"); // 强制类型转换:Type -> TypeVariable(实际使用其实现类 TypeVariableImpl) TypeVariable typeVariable = (TypeVariable) fieldT.getGenericType(); /** * TypeVariable.getBounds(): 获取【表示“泛型的类型变量的上限”的 Type】 * 该变量可能会 extend 多个类型,所以返回值为 Type[] 数组; * 如果未显式声明上限,则上限为 {@code Object}。 */ Type[] types = typeVariable.getBounds(); for(Type type : types){ System.out.println(type); // class java.lang.Number // interface java.io.Serializable // interface java.lang.Comparable } } public static void testGetGenericDeclaration() throws NoSuchFieldException { Field fieldT = TypeVariableDemo.class.getDeclaredField("t"); // 强制类型转换:Type -> TypeVariable(实际使用其实现类 TypeVariableImpl) TypeVariable typeVariable = (TypeVariable) fieldT.getGenericType(); /** * TypeVariable.getGenericDeclaration(): 获取【“声明该类型变量的实体(GenericDeclaration)”】 * 即,“类型变量的声明位置” */ GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration(); System.out.println(genericDeclaration); // class com.eijux.springdemo1.TypeVariableDemo } public static void testGetName() throws NoSuchFieldException { Field fieldT = TypeVariableDemo.class.getDeclaredField("t"); // 强制类型转换:Type -> TypeVariable(实际使用其实现类 TypeVariableImpl) TypeVariable typeVariable = (TypeVariable) fieldT.getGenericType(); /** * TypeVariable.getGenericDeclaration(): 获取【“类型变量在源码中定义的名称”】 * 即,“类型变量的声明位置” */ String name = typeVariable.getName(); System.out.println(name); // T } public static void main(String[] agrs) throws NoSuchFieldException { testTypeVariable(); testGetBounds(); testGetGenericDeclaration(); testGetName(); } }
示例:WildcardType
package com.eijux.springdemo1; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.List; public class WildcardTypeDemo { private List<? extends Number> listNum; private List<? super String> listStr; public static void testWildcardTypeDemo() throws NoSuchFieldException { Field fieldListNum = WildcardTypeDemo.class.getDeclaredField("listNum"); // 强制类型转换:Type -> ParameterizedType(实际使用其实现类 ParameterizedTypeImpl) ParameterizedType typeListNum = (ParameterizedType) fieldListNum.getGenericType(); // 获取:表示“泛型的实际类型”的 Type Type[] typesListNum = typeListNum.getActualTypeArguments(); System.out.println(typesListNum[0].getClass()); //class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl } public static void testGetUpperBounds() throws NoSuchFieldException { Field fieldListNum = WildcardTypeDemo.class.getDeclaredField("listNum"); // 强制类型转换:Type -> ParameterizedType(实际使用其实现类 ParameterizedTypeImpl) ParameterizedType typeListNum = (ParameterizedType) fieldListNum.getGenericType(); // 获取:表示“泛型的实际类型“的 Type Type[] typesListNum = typeListNum.getActualTypeArguments(); /** * WildcardType.getUpperBounds(): 获取【表示“泛型通配符的类型上限”的 Type】 * 通配符可能会 extend 多个类型,所以返回值为 Type[] 数组; */ Type[] types = ((WildcardType) typesListNum[0]).getUpperBounds(); for (Type type : types) { System.out.println(type); // class java.lang.Number } } public static void testGetLowerBounds() throws NoSuchFieldException { Field fieldListStr = WildcardTypeDemo.class.getDeclaredField("listStr"); // 强制类型转换:Type -> ParameterizedType(实际使用其实现类 ParameterizedTypeImpl) ParameterizedType typeListStr = (ParameterizedType) fieldListStr.getGenericType(); /** * ParameterizedType.getActualTypeArguments(): 获取【表示“泛型的实际类型”的 Type】 * 可能会存在多个泛型,例如 Map<K,V>,会返回 Type[]; */ Type[] typesListStr = typeListStr.getActualTypeArguments(); /** * WildcardType.getUpperBounds(): 获取【表示“泛型通配符的类型上限”的 Type】 * 通配符可能会 super 多个类型,所以返回值为 Type[] 数组; */ Type[] types = ((WildcardType) typesListStr[0]).getUpperBounds(); for (Type type : types) { System.out.println(type); // class java.lang.Object } } public static void main(String[] args) throws NoSuchFieldException { testWildcardTypeDemo(); testGetUpperBounds(); testGetLowerBounds(); } }
示例:Class
package com.eijux.springdemo1; import java.lang.reflect.Field; import java.lang.reflect.Type; public class ClassDemo { private ClassDemo classDemo; public static void testClassDemo() throws NoSuchFieldException { /** fieldList 变量: * 类型:Field * 值:"com.eijux.springdemo1.ClassDemo.classDemo" */ Field field = ClassDemo.class.getDeclaredField("classDemo"); /** * Field.getGenericType(): 获取【表示“Field 的类型”的 Type】 * 返回一个 {@code Type} 对象,该对象表示此 {@code Field} 对象所表示的字段的声明类型。 * * typeList 变量: * 类型:Type * 实际类型:Class(Type 的子类) * 值:"class com.eijux.springdemo1.ClassDemo" */ Type type = field.getGenericType(); System.out.println(type); // class com.eijux.springdemo1.ClassDemo } public static void main(String[] args) throws NoSuchFieldException { testClassDemo(); } }
相关:GenericDeclaration
GenericDeclaration;声明“类型变量”的所有实体的公共接口。
——即,该接口定义了哪些地方可以定义“类型变量”(泛型)。
GenericDeclaration接口:
package java.lang.reflect; /** * 声明类型变量的所有实体的公共接口。 * * @since 1.5 */ public interface GenericDeclaration extends AnnotatedElement { /** * 按声明顺序返回{@code TypeVariable}对象数组, * 这些对象表示由此{@code GenericDeclaration}对象表示的泛型声明声明的类型变量。 * * 注意,如果基础泛型声明未声明类型变量,则返回长度为0的数组。 */ public TypeVariable<?>[] getTypeParameters(); }
“GenericDeclaration实现类”与“类型变量的声明位置”
GenericDeclaration 有三个实现类,表示可以声明“类型变量(泛型)”的位置:
- Class:表示“在‘类’上声明泛型”。
- 示例:
/** * 在【类】上声明“类型变量” */ public class GenericDeclarationTest<T> { ... }
- Constructor:表示“在‘构造方法’上声明泛型”。
- 继承于:抽象类“Executable”;
- 示例:
public class GenericDeclarationTest { /** * 在【构造方法】上声明“类型变量” */ public <T> GenericDeclarationTest (T t) { ... } ... }
- Method:表示“在‘方法’上声明泛型”。
- 继承于:抽象类“Executable”;
- 示例:
public class GenericDeclarationTest { ... /** * 在【方法】上声明“类型变量” */ public <T> void test(T t) { ... } }
特别注意:属性上只能使用,而不能定义“类型变量”
示例:
public class GenericDeclarationTest { private T; private List<T> list; ... }
- 如上,属性中使用的 T,须在类上进行声明。
参考
- ↑ 参考:“java.lang.reflect”包相关源码
- ↑ 2.0 2.1 2.2 2.3
ParameterizedType、GenericArrayType、TypeVariable、WildcardType 的区别与关联:
- GenericArrayType 表示 ParameterizedType / TypeVariable 类型的数组。
- “元素类型”通过
GenericArrayType.getGenericComponentType()
获取; - “元素类型”:
- 可以为 ParameterizedType 类型(如“
List<T>[]
”的元素), - 也可以为 TypeVariable 类型(如“
T[]
”的元素);
- 可以为 ParameterizedType 类型(如“
- “元素类型”通过
- ParameterizedType 表示“参数化类型”整体。
- “类型参数”通过
ParameterizedType.getActualTypeArguments()
获取; - “类型参数”:
- 可以为 TypeVariable 类型(如“
List<T>
”的类型参数), - 也可以是 Class 类型(如“
List<String>
”的类型参数);
- 可以为 TypeVariable 类型(如“
- “类型参数”通过
- TypeVariable 仅表示“类型变量”。
- WildcardType 仅表示“泛型表达式”。
public class TypeDemo<T> { private T[] t; private List<T> list_1; private List<String> list_2; private List<T>[] listArray_1; private List<String>[] listArray_2; private List<? super String> listStr; ... }
- t:
- 类型:ParameterizedType
- 类型参数:“T”,其类型:TypeVariable
- list_1:
- 类型:ParameterizedType
- 类型参数:“T”,其类型:TypeVariable
- list_2:
- 类型:ParameterizedType
- 类型参数:“String”,其类型:Class
- listArray_1:
- 类型:GenericArrayType
- 元素:“List<T>”,其类型:ParameterizedType
- 元素的类型参数:“T”,其类型:TypeVariable
- listArray_2:
- 类型:GenericArrayType
- 元素:“List<String>”,其类型:ParameterizedType
- 元素的类型参数:“String”,其类型:Class
- listStr:
- 类型:ParameterizedType
- 通配符表达式:“? super String”,其类型:WildcardType
- GenericArrayType 表示 ParameterizedType / TypeVariable 类型的数组。
- ↑ 参考:Java中的Type