java Type 详解

Set set;

List aList;

static class Holder {

}

}

public class TestHelper {

public static void testParameterizedType() {

Field f = null;

try {

Field[] fields = ParameterizedTypeBean.class.getDeclaredFields();

// 打印出所有的 Field 的 TYpe 是否属于 ParameterizedType

for (int i = 0; i < fields.length; i++) {

f = fields[i];

PrintUtils.print(f.getName()

  • " getGenericType() instanceof ParameterizedType "

  • (f.getGenericType() instanceof ParameterizedType));

}

getParameterizedTypeMes(“map” );

getParameterizedTypeMes(“entry” );

} catch (NoSuchFieldException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SecurityException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

private static void getParameterizedTypeMes(String fieldName) throws NoSuchFieldException {

Field f;

f = ParameterizedTypeBean.class.getDeclaredField(fieldName);

f.setAccessible(true);

PrintUtils.print(f.getGenericType());

boolean b=f.getGenericType() instanceof ParameterizedType;

PrintUtils.print(b);

if(b){

ParameterizedType pType = (ParameterizedType) f.getGenericType();

PrintUtils.print(pType.getRawType());

for (Type type : pType.getActualTypeArguments()) {

PrintUtils.print(type);

}

PrintUtils.print(pType.getOwnerType()); // null

}

}

}

print:map getGenericType() instanceof ParameterizedType true

print:set1 getGenericType() instanceof ParameterizedType true

print:clz getGenericType() instanceof ParameterizedType true

print:holder getGenericType() instanceof ParameterizedType true

print:list getGenericType() instanceof ParameterizedType true

print:str getGenericType() instanceof ParameterizedType false

print:i getGenericType() instanceof ParameterizedType false

print:set getGenericType() instanceof ParameterizedType false

print:aList getGenericType() instanceof ParameterizedType false

print:entry getGenericType() instanceof ParameterizedType true

print:java.util.Map<java.lang.String, com.xujun.gennericity.Person>

print:true

print:interface java.util.Map

print:class java.lang.String

print:class com.xujun.gennericity.Person

print:null

print:java.util.Map.java.util.Map$Entry<java.lang.String, java.lang.String>

print:true

print:interface java.util.Map$Entry

print:class java.lang.String

print:class java.lang.String

print:interface java.util.Map


TypeVariable 变量


比如 public class TypeVariableBean<K extends InputStream & Serializable, V> ,K ,V 都是属于类型变量。

主要方法

  • Type[] getBounds(); 得到上边界的 Type数组,如 K 的上边界数组是 InputStream 和 Serializable。 V 没有指定的话,上边界是 Object

  • D getGenericDeclaration(); 返回的是声明这个 Type 所在的类 的 Type

  • String getName(); 返回的是这个 type variable 的名称

public class TypeVariableBean<K extends InputStream & Closeable, V> {

// K 的上边界是 InputStream

K key;

// 没有指定的话 ,V 的 上边界 属于 Object

V value;

// 不属于 TypeTypeVariable

V[] values;

String str;

List kList;

}

TypeVariableBean bean = new TypeVariableBean<FileInputStream, String>();

fk = TypeVariableBean.class.getDeclaredField(“key”);

eyType = (TypeVariable) fk.getGenericType();

System.out.println(keyType.getName());System.out.println(keyType.getGenericDeclaration());

执行上述代码,将可以看到如下的效果

K

class com.xujun.gennericity.beans.TypeVariableBean


GenericArrayType


represents an array type whose component

type is either a parameterized type or a type variable.

简单来说就是:范型数组,组成数组的元素中有范型则实现了该接口; 它的组成元素是 ParameterizedType 或 TypeVariable 类型

// 属于 GenericArrayType

List[] pTypeArray;

// 属于 GenericArrayType

T[] vTypeArray;

// 不属于 GenericArrayType

List list;

// 不属于 GenericArrayType

String[] strings;

// 不属于 GenericArrayType

Person[] ints;

下面我们一起来看一下例子

public class GenericArrayTypeBean {

public void test(List[] pTypeArray, T[] vTypeArray,

List list, String[] strings, Person[] ints) {

}

}

public static void testGenericArrayType() {

Method method = GenericArrayTypeBean.class.getDeclaredMethods()[0];

System.out.println(method);

// public void test(List[] pTypeArray, T[]

// vTypeArray,List list, String[] strings, Person[] ints)

Type[] types = method.getGenericParameterTypes(); // 这是 Method 中的方法

for (Type type : types) {

System.out.println(type instanceof GenericArrayType);// 依次输出true,true,false,false,false

}

}

输出结果

public void com.xujun.gennericity.beans.GenericArrayTypeBean.test(java.util.List[],java.lang.Object[],java.util.List,java.lang.String[],com.xujun.gennericity.Person[])

true

true

false

false

false


WildcardType 通配符的类型


{@code ?}, {@code ? extends Number}, or {@code ? super Integer} 这些类型 都属于 WildcardType

extends 用来指定上边界,没有指定的话上边界默认是 Object, super 用来指定下边界,没有指定的话为 null。

几个主要方法介绍

  • Type[] getLowerBounds() 得到上边界 Type 的数组

  • Type[] getUpperBounds() 得到下边界 Type 的数组

下面一起来看一下例子。

public class WildcardTypeBean {

private List<? extends Number> a; // a没有下界,

// 没有指定的话,上边界默认是 Object ,下边界是 String

private List<? super String> b;

private List c;

private Class<?> aClass;

}

public static void testWildCardType() {

try {

Field[] fields = WildcardTypeBean.class.getDeclaredFields();

for (int i = 0; i < fields.length; i++) {

Field field = fields[i];

Type type = field.getGenericType();

String nameString = field.getName();

PrintUtils.print(“下面开始打印” + nameString + “是否具有通配符”);

if (!(type instanceof ParameterizedType)) {

PrintUtils.print(“---------------------------”);

continue;

}

ParameterizedType parameterizedType = (ParameterizedType) type;

type = parameterizedType.getActualTypeArguments()[0];

if (!(type instanceof WildcardType)) {

PrintUtils.print(“---------------------------”);

continue;

}

WildcardType wildcardType = (WildcardType) type;

Type[] lowerTypes = wildcardType.getLowerBounds();

if (lowerTypes != null) {

PrintUtils.print(“下边界”);

PrintUtils.printTypeArr(lowerTypes);

}

Type[] upTypes = wildcardType.getUpperBounds();

if (upTypes != null) {

PrintUtils.print(“上边界”);

PrintUtils.printTypeArr(upTypes);

}

PrintUtils.print(“---------------------------”);

}

Field fieldA = WildcardTypeBean.class.getDeclaredField(“a”);

Field fieldB = WildcardTypeBean.class.getDeclaredField(“b”);

// 先拿到范型类型

PrintUtils.print(fieldA.getGenericType() instanceof ParameterizedType);

PrintUtils.print(fieldB.getGenericType() instanceof ParameterizedType);

ParameterizedType pTypeA = (ParameterizedType) fieldA.getGenericType();

ParameterizedType pTypeB = (ParameterizedType) fieldB.getGenericType();

// 再从范型里拿到通配符类型

PrintUtils.print(pTypeA.getActualTypeArguments()[0] instanceof WildcardType);

PrintUtils.print(pTypeB.getActualTypeArguments()[0] instanceof WildcardType);

WildcardType wTypeA = (WildcardType) pTypeA.getActualTypeArguments()[0];

WildcardType wTypeB = (WildcardType) pTypeB.getActualTypeArguments()[0];

// 方法测试

System.out.println(wTypeA.getUpperBounds()[0]);

System.out.println(wTypeB.getLowerBounds()[0]);

// 看看通配符类型到底是什么, 打印结果为: ? extends java.lang.Number

System.out.println(wTypeA);

} catch (NoSuchFieldException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SecurityException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

java Type 总结


Type及其子接口的来历

  • 泛型出现之前的类型

没有泛型的时候,只有原始类型。此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型。

  • 泛型出现之后的类型

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
出现之后的类型

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-IgwiaRwR-1715702230752)]

[外链图片转存中…(img-4g1UZos9-1715702230752)]

[外链图片转存中…(img-buwE2QdP-1715702230753)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值