Java源码解析之TypeVariable详解
TypeVariable,类型变量,描述类型,表示泛指任意或相关一类类型,也可以说狭义上的泛型(泛指某一类类型),一般用大写字母作为变量,比如K、V、E等。
源码
public interface TypeVariable<D extends GenericDeclaration> extends Type { //获得泛型的上限,若未明确声明上边界则默认为Object Type[] getBounds(); //获取声明该类型变量实体(即获得类、方法或构造器名) D getGenericDeclaration(); //获得名称,即K、V、E之类名称 String getName(); }
概述
说到TypeVariable<D>就不得不提起java泛型中另一个比较重要的接口对象,GenericDeclaration接口对象。该接口用来定义哪些对象上是可以声明(定义)范型变量,所谓范型变量就是<E extends List>或者<E>, 也就是TypeVariable<D>这个接口的对应的对象,TypeVariable<D>中的D是extends GenericDeclaration的,用来通过范型变量反向获取拥有这个变量的GenericDeclaration。
目前实现GenericDeclaration接口的类包括Class, Method, Constructor,也就是说只能在这几种对象上进行范型变量的声明(定义)。GenericDeclaration的接口方法getTypeParameters用来逐个获取该GenericDeclaration的范型变量声明。详情可查看:Java源码解析之GenericDeclaration详解
类型变量的声明(定义):<E>,前后需加上尖括号
//1.在类(Class)上声明(定义)类型变量 class A<T>{ T a; }//之后这里可用任意类型替换T,例如 A<String> as = new A<String>(); //是否看着有点像集合?不错,集合就是泛型的一个典型运用 //2.在方法上声明(定义) public <E> void test(E e){} //方法上,类型变量声明(定义)不是在参数里边,而且必须在返回值之前,static等修饰后 //3.声明(定义)在构造器上 public <K> A(K k){}
【注意】类型变量声明(定义)的时候不能有下限(既不能有super),否则编译报错。为什么?T extends classA表示泛型有上限classA,当然可以,因为这样,每一个传进来的类型必定是classA(具有classA的一切属性和方法),但若是T super classA,传进来的类型不一定具有classA的属性和方法,当然就不适用于泛型,说的具体点:
//假设 class A<T super classA>{ T t; public void test(){ //这个时候你不能用t干任何事,因为你不确定t具有哪些属性和方法 //当然,t肯定是有Object方法的,但没意义 } }
源码详解
1.getBounds
获得该类型变量的上限(上边界),若无显式定义(extends),默认为Object,类型变量的上限可能不止一个,因为可以用&符号限定多个(这其中有且只能有一个为类或抽象类,且必须放在extends后的第一个,即若有多个上边界,则第一个&后必为接口)。
class A<K extends classA & interfaceB, V>{ K key; V value; public static void main(String[] args) throws Exception { Type[] types = Main.class.getTypeParameters(); for(Type type : types){ TypeVariable t = (TypeVariable)type; System.out.println(t.getGenericDeclaration()); int size = t.getBounds().length; System.out.println(t.getBounds()[size - 1]); System.out.println(t.getName() + "\n-------------分割线-------------"); } } } //输出结果 class com.fcc.test.Main interface com.fcc.test.interfaceB K -------------分割线------------- class com.fcc.test.Main class java.lang.Object V -------------分割线-------------
2.getGenericDeclaration
获得声明(定义)这个类型变量的类型及名称,即如:
class com.xxx.xxx.classA 或
public void com.fcc.test.Main.test(java.util.List) 或
public com.fcc.test.Main()
Constructor constructor = Main.class.getConstructor(); TypeVariable typeVariable = constructor.getTypeParameters()[0]; System.out.println(typeVariable.getGenericDeclaration()); //获得方法中声明(定义)的类型变量与上面类似
3.getName
获得这个类型变量在声明(定义)时候的名称
总结
以上就是本文关于Java源码解析之TypeVariable详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Java源码解析之object类、java.lang.Void类源码解析等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Fedora32下编译安装Qemu5.1并创建ARM版本Linux虚拟机
- 面试官想问的HashMap,都在这一篇里面了!
- CentOS7下使用Mondo Rescue实现系统全备份
- CentOS7下搭建Rsyslog Server记录远程主机系统日志
- 企业运维经典面试题汇总(4)
- 使用QEMU模拟树莓派Raspberry Pi
- Octave梯度下降法最优化代价函数的一个例子—ML Note 38
- Spring Boot入门系列(十八)mybatis 使用注解实现增删改查,无需xml文件!
- Mongodb多键索引之嵌套文档
- MySQL中的这几类日志,你一定要知道
- 微服务技术栈:API网关中心,落地实现方案
- 你的数据库服务器IO调度算法不对,难怪那么慢
- Android 11 强制用户使用系统相机?
- LeetCode题目38:外观数列
- GPUManager虚拟化方案