Java反射源码剖析系列--Type接口

之前的博客中(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接口的继承树是长什么样子的。

Java反射源码剖析系列--Type接口_第1张图片

可以看到有四个接口继承Type接口,分别是:

  • WildcardType(对应通配符类型表达式)
  • TypeVariable(对应类型变量)
  • ParameterizedType(对应参数化类型)
  • GenericArrayType(对应数组类型)

所以也很清楚了,在jdk1.5之前,或者说在泛型被支持之前,Java语言模型的类型就两个:原生类型和基础类型。后面几个都是之后加上去的。

那接下来就简单介绍一下这五种类型:

  • 原生类型:包括数组,类,接口,注解,枚举等等的Class类型(就是平时我们写的类,接口啥的)。
  • 基础类型:八种基本类型byte, short, int, long, float, double, boolean, char(这个大家肯定都很熟啦,平时一直用的)。
  • 参数化类型:使用泛型编写的类的类型,比如List,Collection等等,一般长这样:List、Map等等。
  • 类型变量:表示编译前泛型的信息,比如T,E之类的类型变量,可以泛指任何类。
  • 数组类型:由泛型类的实例组成的数组类型,比如A[],T[][]等等。

有个很好的例子可以说明这些类型的关系:

List []:这里的List就是ParameterizedType,T就是TypeVariable,T ? entends就是WildcardType(注意,WildcardType不是Java类型,而是一个表达式),整个List []就是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());
    }

}

之后四个子接口的详细介绍也会慢慢填上,先留个坑:)

你可能感兴趣的:(Java反射源码剖析系列--Type接口)