Type 是Java 编程语言中所有类型的公共高级接口(官方解释),也就是Java 中所有类型的”爹“。其中”所有类型“的描述尤为指的关注。它并不是我们平常工作中经常使用的int、String、List、Map等数据类型,而是从Java语言角度磊说,对基本类型、引用类型向上的抽象
Java Type
- Type 体系中的类型
- Type 与子类,子接口的关系
- Class
- Type
- ParameterizedType (参数化类型)
- GenericArrayType (泛型数组类型)
- TypeVariable (类型变量类型)
- GenericDeclaration
- 【extends 和 super的区别】
- WildcardType (泛型表达式或者通配符表达式)
- 示例
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());
}
}
}