java 反射 type_java 反射学习笔记(三)—— Type接口

[TOC]

bc21159c0549

Type接口.png

概述

Type是Java语言中所有类型的公共高级接口。

这个所有类型是从Java语言角度来说的,如上图可见(Class类也实现了该接口),Type体系包括了Class、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)。

Type的使用

1.Class

type有一个实现类和4个实现接口,当需要描述的类型是:普通的类,自定义的类,也就是和 泛型无关的类 ,java可以直接将这个type类强转为Class。

2. TypeVariable

TypeVariable 是类型变量的常用超级接口。类型变量在反射方法首次需要时创建。指的是List中的T,实际的Java类型是TypeVariableImpl。也可以对类型变量加上extend限定,这样会有类型变量对应的上限。

获取一个对象的泛型声明方式通常是通过class类,class类实现了GenericDecalaration接口,该接口只有一个方法,返回的是代表了泛型声明的泛型变量数组。

public interface GenericDeclaration extends AnnotatedElement {

public TypeVariable>[] getTypeParameters();

}

TypeVariable extends Class extends User>>[] typeVariables = user.getClass().getTypeParameters();

for (TypeVariable extends Class extends User>> typeVariable :typeVariables){

System.out.println(typeVariable.getName()); //输出T

Stream.of(typeVariable.getBounds()).forEach(System.out::println); //没有上限默认输出Object

System.out.println(typeVariable.getGenericDeclaration()); // 输出user,因为是在user类上声明的泛型

}

public interface TypeVariable extends Type, AnnotatedElement {

/**

*返回表示此类型变量上边界的Type对象数组

*/

Type[] getBounds();

/**

* Returns the {@code GenericDeclaration} object representing the

* generic declaration declared this type variable.

*

* @return the generic declaration declared for this type variable.

*

* @since 1.5

*/

D getGenericDeclaration();

/**

* Returns the name of this type variable, as it occurs in the source code.

*

* @return the name of this type variable, as it appears in the source code

*/

String getName();

}

3. ParameterizedType

表示一个参数化类型,也就是泛型,例如List,该接口内主要有3个方法

/**

* ParameterizedType represents a parameterized type such as

* Collection<String>.

*/

public interface ParameterizedType extends Type {

/**

* Returns an array of {@code Type} objects representing the actual type

* arguments to this type.

* 获取泛型中的实际类型

*/

Type[] getActualTypeArguments();

/**

* Returns the {@code Type} object representing the class or interface

* that declared this type.

*

* @return the {@code Type} object representing the class or interface

* that declared this type

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

*/

Type getRawType();

/**

* 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}.

*

*

If this type is a top-level type, {@code null} is returned.

*

* @return a {@code Type} object representing the type that

* this type is a member of. If this type is a top-level type,

* 获取泛型的拥有者

*/

Type getOwnerType();

}

通常,我们可以使用该接口来检验泛型是否被参数化。通过instance判断是已经参数化了之后,再通过getactualTypeArguments方法获取参数化类型。具体可参考下面的代码。

如何获取参数化类型

这里说的参数化类型指的就是泛型的实际形式,即将类型以参数的方式进行传递。这里需要注意的点是Java是共享泛型模式,子类的泛型标识在编译时就会被擦除,不会写入到实际子类型中,所以无法得到自身标识的类型参数。要想得到泛型信息,只能从上层类型中得到(可以是继承的父类或者实现的接口)。从下面的代码中也能看出,调用Son.getclass方法能够获得类型参数class.User,而调用Fathor的该方法时却会报错。从代码也能看出,我们得到的参数类型也不是通过构造方法传入的类型,而是从父类传递下来的参数类型。

public class Fathor {

public void getClazz(){

Type type = this.getClass().getGenericSuperclass();

System.out.println(type);

Type[] types = ((ParameterizedType)type).getActualTypeArguments();

Stream.of(types).forEach(System.out::println);

}

}

public class Son extends Fathor {

@Override

public void getClazz() {

Type type = this.getClass().getGenericSuperclass();

System.out.println(type);

if(type instanceof ParameterizedType) {

Type[] types = ((ParameterizedType)type).getActualTypeArguments();

Stream.of(types).forEach(System.out::println);

}

}

}

public static void main(String[] args) {

new Son().getClazz();

new Fathor().getClazz();

}

//输出

instance.Fathor

class instance.User

class java.lang.Object

Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

at instance.Fathor.getClazz(Fathor.java:15)

at wytest.Test2.main(Test2.java:15)

4. GenericArrayType

泛型数组类型,例如List[]

public interface GenericArrayType extends Type {

//返回泛型数组中元素的Type类型,

Type getGenericComponentType();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值