Java Type

Type 是Java 编程语言中所有类型的公共高级接口(官方解释),也就是Java 中所有类型的”爹“。其中”所有类型“的描述尤为指的关注。它并不是我们平常工作中经常使用的int、String、List、Map等数据类型,而是从Java语言角度磊说,对基本类型、引用类型向上的抽象

Type 体系中的类型

Type 体系中类型的包括

  • 原始类型(Class):不仅仅包括我们平常所指的类,还包括枚举、数组、注解等
  • 参数化类型(ParameterizedType):就是我们平常所用到的泛型List、Map
  • 泛型数组类型(GenericArrayType):并不是我们平常所使用的数组String[] 、byte[]。而是带有泛型的数组,即 T[]
  • 类型变量(TypeVariable):是各种类型变量的公共父接口,就是泛型里面的类似T、E。 在这需要强调的是,TypeVariable代表着泛型中的变量,而ParameterizedType则代表整个泛型;
  • 基本类型(Class):也就是我们所说的java 基本类型,即int、float、double等

Type类几乎在各种框架中都能看到,尤其是涉及代理,反射的业务。理解好Type类也会对今后框架封装,源码解读有很大好处

Type 与子类,子接口的关系

在这里插入图片描述

Class

当需要描述的类型是:

  • 普通的java类(比如String,Integer,Method等等)
  • 数组
  • 自定义类(比如我们自己定义的TestReflect类)
  • java基本类型(比如int,float等)
  • 可能还有其他的类

那么java会选择Class来作为这个Type的实现类,我们甚至可以直接把这个Type强行转换类型为Class。
这些类基本都有一个特点:基本和泛型无关,其他4种Type的类型,基本都是泛型的各种形态

Type

public interface Type {
    @RecentlyNonNull
    default String getTypeName() {
        throw new RuntimeException("Stub!");
    }
}

ParameterizedType (参数化类型)

ParameterizedType 是参数化类型,即泛型,类似List、Map<Integer, String>、List<? extends Number>带有类型参数的类型,也可以是自定义的,再调用getRawType()与getActualTypeArguments()两个方法,就可以得到声明此参数化类型的类(java.lang.Comparable)和实际的类型参数数组([? super T]),而这个? super T又是一个WildcardType类型。

 // 获取泛型的类型,比如 Map<Integer,String> 获取的是 Integer和String
    Type[] getActualTypeArguments();
    // 获取<> 前面的类型,比如 Map<Integer,String> 获取的是Map
    Type getRawType();
    // 如果这个类型是某个类型所属,则获取这个所有者的类型,否则返回null,比如Map.Entry<Sting,String>,会返回Map
    Type getOwnerType();


	//举例
	//参数,List<String>[] p3
	public class TestReflect {
		public static void test(
	            List<TestReflect> p1,
            	Map<String, TestReflect> p2
	    ) {}
    }
    Method[] methods = TestReflect.class.getMethods();
    Method method=methods[i].eques("test");
    Type[] types=method.getGenericParameterTypes();
    //第一个参数 List<TestReflect> p1
    Type type3=types[0];
    Type[] parameterizedType1=((ParameterizedType)type1).getActualTypeArguments();
    Class parameterizedType1_0=(Class)parameterizedType1[0];
    System.out.println("获取泛型的类型 :"+parameterizedType1_0.getName());
    //【打印log】 获取泛型的类型 :com.wf.javatype.TestReflect

	//第二个参数,Map<String,TestReflect> p2
    Type type2=types[2];
    Type[] parameterizedType2=((ParameterizedType)type2).getActualTypeArguments();
    Class parameterizedType2_0=(Class)parameterizedType2[0];
    System.out.println("获取泛型的类型 1:"+parameterizedType2_0.getName());
    Class parameterizedType2_1=(Class)parameterizedType2[1];
    System.out.println("获取泛型的类型 2:"+parameterizedType2_1.getName());
    //【打印log】
    //获取泛型的类型 1:java.lang.String
	//获取泛型的类型 2:com.wf.javatype.TestReflect

GenericArrayType (泛型数组类型)

泛型数组类型,用来描述ParameterizedType、TypeVariable类型的数组;即List[] 、T[]等

public interface GenericArrayType extends Type {
    /**
     *  获取泛型数组中元素的类型,要注意的是:
  无论从左向右有几个[]并列,这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值。
     */
    Type getGenericComponentType();

	//举例1
	//参数,List<String>[] p3
	public class TestReflect {
		public static void test(
	            List<String>[] p3,
	            Map<String,TestReflect>[] p4
	    ) {}
    }
    Method[] methods = TestReflect.class.getMethods();
    Method method=methods[i].eques("test");
    Type[] types=method.getGenericParameterTypes();
    Type type3=types[0];
    Type genericArrayType3=((GenericArrayType)type3).getGenericComponentType();
    System.out.println("类型 :"+genericArrayType3.getTypeName());
    //【打印log】 类型 :java.util.List<java.lang.String>
	
	//举例2
	Type type4=types[1];
    Type genericArrayType4=((GenericArrayType)type4).getGenericComponentType();
    ParameterizedType parameterizedType4=(ParameterizedType)genericArrayType4;
    System.out.println("获取泛型类型 :"+parameterizedType4.getTypeName());
    //【打印log】获取泛型类型 :java.util.Map<java.lang.String, com.wf.javatype.TestReflect>
    Type[] parameterizedType4Arr=parameterizedType4.getActualTypeArguments();
    Class class4_0=(Class)parameterizedType4Arr[0];
    System.out.println("获取泛型类型 1:"+class4_0.getName());
    //【打印log】获取泛型类型 1:java.lang.String
    Class class4_1=(Class)parameterizedType4Arr[1];
    System.out.println("获取泛型类型 2:"+class4_1.getName());
    //【打印log】获取泛型类型 2:com.wf.javatype.TestReflect
}

TypeVariable (类型变量类型)

类型变量,即泛型中的变量;例如:T、K、V等变量,可以表示任何类;在这需要强调的是,TypeVariable代表着泛型中的变量,而ParameterizedType则代表整个泛型;


public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
    // 获取泛型的上限,无显示定义(extends),默认为Object
    Type[] getBounds();
    // 获取声明改类型变量实体(即获取类,方法或构造器名)
    D getGenericDeclaration();
    // 获取名称,即K、V、E之类名称
    String getName();
    // 
     AnnotatedType[] getAnnotatedBounds();

认识TypeVariable之前,我们先来看另一个接口 GenericDecalaration;
GenericDeclaration 有三个直接子类 Class、Construtor、Method、Executable也就是说只能在这几种对象上进行范型变量的声明(定义)。

GenericDeclaration
//1.在类(Class)上声明(定义)类型变量
class A<T>{
  T a;
}//之后这里可用任意类型替换T,例如
A<String> as = new A<String>();
//是否看着有点像集合?不错,集合就是泛型的一个典型运用

//2.在方法上声明(定义,方法上,类型变量声明(定义)不是在参数里边,而且必须在返回值之前,static等修饰后
public <E> void test(E e){}


//3.声明(定义)在构造器上
public <K> A(K k){}

//4. 第四种没有使用过,有会的大佬可以指点我一下

【注意】:类型变量声明(定义)的时候不能有下限(super),否则编译器报错。为什么T extend classA 表示泛型有上限classA 可以,因为每一个传进来的类型必定是classA(具有classA 的一切属性和方法) ,但若是T super classA,传进来的类型不一定具有classA的属性和方法,当然就不使用与泛型

【extends 和 super的区别】
关键字说明
 ? 通配符类型
<? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
<? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
看了这个我是不太明白,换成白话是这个意思:
List<? extends T> 是说 这个list放的是T或者T的子类型的对象,但是不能确定具体是什么类型,所以可以get(),不能add()(可以add null值)

List<? super T> 是说这个list放的是至少是T类型的对象,所以我可以add T或者T的子类型,但是get得到的类型不确定,所以不能获取

WildcardType (泛型表达式或者通配符表达式)

当需要描述的类型是泛型类,而且泛型类中的泛型被定义为(? extends xxx)或者(? super xxx)这种类型,比如List<? extends TestReflect>,这个类型首先将由ParameterizedType实现,当调用ParameterizedType的getActualTypeArguments()方法后得到的Type就由WildcardType实现。

public interface WildcardType extends Type {
	//得到的是类型的上边界的Type数组,实际上就是类型的直接父类,也就是extends后面的类型。
	//显然在当前java的设定中,这个数组只可能有一个元素,因为java现在只能extends一个类。如果实在没写extends,那他的直接父类就是Object
    @RecentlyNonNull
    Type[] getUpperBounds();

    //得到的是类型的下边界的Type数组,有super关键字时可能会用到,经测试不会得到类型的子类,
    //而是只得到super关键字后面的类型,如果没写super关键字,则返回空数组。
    @RecentlyNonNull
    Type[] getLowerBounds();
}

示例

public class TestReflect {

    public static void test(
            TestReflect p0,
            List<TestReflect> p1,
            Map<String, TestReflect> p2,
            List<String>[] p3,
            Map<String, TestReflect>[] p4,
            List<? extends TestReflect> p5,
            Map<? extends TestReflect, ? super TestReflect> p6
    ) {}
}

@Test
public  void main() {
	//获取 TestReflect 类的所有方法
	Method[] methods = TestReflect.class.getMethods();
	for (int i = 0; i < methods.length; i++) {
            Method method=methods[i];
            if(method.getName().equals("test")){
                System.out.println("TestReflect 的 方法: "+method.getName());
                Type[] types=method.getGenericParameterTypes();

                //第一个参数,TestReflect p0
                Class type0=(Class)types[0];
                //【打印log】 type0 :com.wf.javatype.TestReflect
                System.out.println("type0 :"+type0.getName());

				//第二个参数,List<TestReflect> p1
                //获取泛型的类型
                Type type1=types[1];
                Type[] parameterizedType1=((ParameterizedType)type1).getActualTypeArguments();
                Class parameterizedType1_0=(Class)parameterizedType1[0];
                //【打印log】获取泛型的类型 :com.wf.javatype.TestReflect
                System.out.println("获取泛型的类型 :"+parameterizedType1_0.getName());


				//第三个参数,Map<String,TestReflect> p2
                Type type2=types[2];
                Type[] parameterizedType2=((ParameterizedType)type2).getActualTypeArguments();
                Class parameterizedType2_0=(Class)parameterizedType2[0];
                //【打印log】 获取泛型的类型 1:java.lang.String
                System.out.println("获取泛型的类型 1:"+parameterizedType2_0.getName());
                Class parameterizedType2_1=(Class)parameterizedType2[1];
                //【打印log】获取泛型的类型 2:com.wf.javatype.TestReflect
                System.out.println("获取泛型的类型 2:"+parameterizedType2_1.getName());
            }
        }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值