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类源码解析等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!