之前的博客中(Java反射源码剖析系列--Member接口),我们查看了Executable抽象类的声明,发现它实现了两个接口,一个是Member接口,关于Member的详细说明可以点开Java反射源码剖析系列--Member接口查看。另一个接口就是GenericDeclaration接口,我们看一下这个接口的声明:
public interface GenericDeclaration extends AnnotatedElement { public TypeVariable<?>[] getTypeParameters(); }
继承的AnnotatedElement是支持注解功能的一个接口,我们暂时不管它,看一下这个接口中仅有的一个方法getTypeParameters。它的返回是一个TypeVariable类型的数组,那这个TypeVariable干什么用的呢?继续对源码下挖,来看一下这个TypeVariable的声明:
public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
从源码中我们可以看出,TypeVariable它继承了两个接口:
- Type接口
- AnnotatedElement接口
AnnotatedElment接口照例,我们暂时不管它,让我们好好看看这个Type接口,了解一下这个Type接口有什么作用。
那么Type接口是用来干什么的?
jdk1.8 api中是这样说明的,Type接口是所有Java编程语言中所有类型的父接口,这是一个很大的定义,有种对Java语言所有所有类型的抽象的感觉(个人感觉)。
那这个所谓的所有类型指的是哪些类型呢?
分别有以下五种类型:
- 原生类型(raw types)
- 参数化类型( parameterized types)
- 数组类型(array types)
- 类型变量(type variables)
- 基础类型(primitive types)
这些类型其实有很大一部分都是用来支持Java泛型的,继承Type接口的接口(包括Type接口)都是jdk1.5之后的产物。我们来看一下Type接口的继承树是长什么样子的。
可以看到有四个接口继承Type接口,分别是:
- WildcardType(对应通配符类型表达式)
- TypeVariable<D>(对应类型变量)
- ParameterizedType(对应参数化类型)
- GenericArrayType(对应数组类型)
所以也很清楚了,在jdk1.5之前,或者说在泛型被支持之前,Java语言模型的类型就两个:原生类型和基础类型。后面几个都是之后加上去的。
那接下来就简单介绍一下这五种类型:
- 原生类型:包括数组,类,接口,注解,枚举等等的Class类型(就是平时我们写的类,接口啥的)。
- 基础类型:八种基本类型byte, short, int, long, float, double, boolean, char(这个大家肯定都很熟啦,平时一直用的)。
- 参数化类型:使用泛型编写的类的类型,比如List,Collection等等,一般长这样:List<T>、Map<Integer, String>等等。
- 类型变量:表示编译前泛型的信息,比如T,E之类的类型变量,可以泛指任何类。
- 数组类型:由泛型类的实例组成的数组类型,比如A<T>[],T[][]等等。
有个很好的例子可以说明这些类型的关系:
List <T ? entends> []:这里的List就是ParameterizedType,T就是TypeVariable,T ? entends就是WildcardType(注意,WildcardType不是Java类型,而是一个表达式),整个List <T ? entends> []就是GenericArrayType。
类型介绍完之后,我们来看看这个接口里面都有什么方法?
public interface Type { default String getTypeName() { return toString(); } }
jdk1.8之前Type类型里面是没有任何方法定义的,所以这个类的作用仅仅是对Java语言所有类型的一个抽象,但是在1.8之后,加入了一个getTypeName方法,用来获取类型的名称,提供了默认的实现。
方法声明 | 作用 | 返回值 |
getTypeName | 获取一个描述类型信息的参数 | 返回字符串类型,描述类型信息 |
测试一下:
package reflect; public class User { private int id; private int name; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getName() { return name; } public void setName(int name) { this.name = name; } public User() { } @Override public String toString() { return "User{" + "id=" + id + ", name=" + name + '}'; } }
测试类:
package reflect; import org.junit.Assert; import org.junit.Test; import java.lang.reflect.Method; public class TestReflect { @Test public void testGetTypeName() throws ClassNotFoundException { Class clazz = Class.forName("reflect.User"); System.out.println(clazz.getTypeName()); } }
之后四个子接口的详细介绍也会慢慢填上,先留个坑:)