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
比如 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
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
{@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();
}
}
Type及其子接口的来历
- 泛型出现之前的类型
没有泛型的时候,只有原始类型。此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型。
- 泛型出现之后的类型
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
由于篇幅原因,就不多做展示了
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
[外链图片转存中…(img-BQ290gTK-1713472878315)]
[外链图片转存中…(img-fhO89ScV-1713472878315)]
[外链图片转存中…(img-H13pB30o-1713472878315)]
[外链图片转存中…(img-cMVb1yls-1713472878316)]
[外链图片转存中…(img-fAQtFuKZ-1713472878316)]
[外链图片转存中…(img-fmNKAgUN-1713472878317)]
由于篇幅原因,就不多做展示了
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!