Java中的Type


Type

下面就用代码的方式,对其中的5大类型:原始类型(Class)、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)、基本类型(Class) 进一步说明;

1.ParameterizedType

ParameterizedType表示参数化类型,也就是泛型,例如List、Set等;

 ParameterizedType

在ParameterizedType接口中,有3个方法,分别是getActualTypeArguments()、 getRawType()、 getOwnerType();

1.1 getActualTypeArguments

获取泛型中的实际类型,可能会存在多个泛型,例如Map,所以会返回Type[]数组;

 值得注意的是,无论<>中有几层嵌套(List),getActualTypeArguments()方法永远都是脱去最外层的<>(也就是List<>),将口号内的内容(Map)返回;

我们经常遇到的List,通过getActualTypeArguments()方法,得到的返回值是TypeVariableImpl对象,也就是TypeVariable类型(后面介绍);

1.2 getRawType

获取声明泛型的类或者接口,也就是泛型中<>前面的那个值;

1.3 getOwnerType

通过方法的名称,我们大概了解到,此方法是获取泛型的拥有者,那么拥有者是个什么意思?

Returns a {@code Type} object representing the type that this type * is a member of. For example, if this type is {@code O.I}, * return a representation of {@code O}. (摘自JDK注释)

通过注解,我们得知,“拥有者”表示的含义--内部类的“父类”,通过getOwnerType()方法可以获取到内部类的“拥有者”;例如: Map 就是 Map.Entry的拥有者;

2.GenericArrayType

泛型数组类型,例如E[] 、T[]、List[] (可以理解为包含泛型变量的数组,因为List[] 中的String其实就是泛型)

注意:list[] 、String[]不是该类型,他们不包含泛型,他们直接是特殊的Class类型

GenericArrayType

在GenericArrayType接口中,仅有1个方法,就是getGenericComponentType(); 

2.1 getGenericComponentType

返回泛型数组中元素的Type类型,即List[] 中的 List(ParameterizedTypeImpl)、T[] 中的T(TypeVariableImpl); 

 值得注意的是,无论是几维数组,getGenericComponentType()方法都只会脱去最右边的[],返回剩下的值;

3.TypeVariable

泛型的类型变量,指的是List、Map中的T,K,V等值,实际的Java类型是TypeVariableImpl(TypeVariable的子类);此外,还可以对类型变量加上extend限定,这样会有类型变量对应的上限;

 TypeVariable

在TypeVariable接口中,有3个方法,分别为getBounds()、getGenericDeclaration()、getName();

3.1 getBounds

获得该类型变量的上限,也就是泛型中extend右边的值;例如 List ,Number就是类型变量T的上限;如果我们只是简单的声明了List(无显式定义extends),那么默认为Object;

 无显式定义extends:

 值得注意的是,类型变量的上限可以为多个,必须使用&符号相连接,例如 List;其中,& 后必须为接口;

3.2 getGenericDeclaration

获取声明该类型变量实体,也就是TypeVariableTest中的TypeVariableTest;

 3.3 getName

获取类型变量在源码中定义的名称;

说到TypeVariable类,就不得不提及Java-Type体系中另一个比较重要的接口---GenericDeclaration;含义为:声明类型变量的所有实体的公共接口;也就是说该接口定义了哪些地方可以定义类型变量(泛型);

通过查看源码发现,GenericDeclaration下有三个子类,分别为Class、Method、Constructor;也就是说,我们定义泛型只能在一个类中这3个地方自定义泛型;

此时,我们不禁要问,我们不是经常在类中的属性声明泛型吗,怎么Field没有实现 GenericDeclaration接口呢?

其实,我们在Field中并没有声明泛型,而是在使用泛型而已!不信,我们实际上代码来看看!

1.首先在Class上定义泛型:

 Class定义泛型

2.我们没有在Class上定义泛型,直接在构造方法上定义泛型

泛型构造

3.同样没有在Class定义泛型,直接在普通方法上定义泛型

泛型方法

4.我们直接在属性上定义

属性上定义泛型

 我们看到,如果不在Class上定义,属性上并不能直接使用!所以,这也是我之前说的属性上并不是定义泛型,而是使用泛型,所以Field并没有实现GenericDeclaration接口!

4.Class

 Type接口的实现类,是我们工作中常用到的一个对象;在Java中,每个.class文件在程序运行期间,都对应着一个Class对象,这个对象保存有这个类的全部信息;因此,Class对象也称之为Java反射的基础;

 通过上面的例子,可以看出,当我们没有声明泛型的时候,我们普通的对象就是一个Class类型,是Type中的一种;

5.WildcardType

?---通配符表达式,表示通配符泛型,但是WildcardType并不属于Java-Type中的一钟;例如:List extends Number> 和 List super Integer>;

 WildcardType

在WildcardType接口中,有2个方法,分别为getUpperBounds()、getLowerBounds();

5.1 getUpperBounds

获取泛型变量的上边界(extends)

5.2 getLowerBounds

获取泛型变量的下边界(super)

以上,就是对Java-Type体系中相关对象的介绍;

 转载:https://blog.csdn.net/weixin_39768444/article/details/114097737

TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
Bing Webmaster Portal Back