java type接口及子接口ParameterizedType,TypeVariable,GenericArrayType,WildcardType例子

简介

public interface Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。

  • 原始类型:一般意义上的java类,由class类实现
  • 参数化类型:ParameterizedType接口的实现类
  • 数组类型:GenericArrayType接口的实现类
  • 类型变量:TypeVariable接口的实现类
  • 基本类型:int,float等java基本类型,其实也是class

使用junit断言,下面例子都可以直接运行通过

ParameterizedType

/** 
 * <p>Title: ParameterizedTypeTest.java</p>  
 * <p>Description: 参数化类型测试</p>  
 * @author    dengjili
 * @date      2020年7月30日  
 */
public class ParameterizedTypeTest {
	static class Foo {
		private List<String> list;
		private Map<String, String> mapping;
		private Map<String, List<String>> data;
	}
	
	@Test
	public void test() throws Exception {
		Field field = Foo.class.getDeclaredField("list");
		Type type = field.getGenericType();
		Assert.assertTrue(type instanceof ParameterizedType);
		Assert.assertEquals(String.class, ((ParameterizedType) type).getActualTypeArguments()[0]);
	}
	
	@Test
	public void test2() throws Exception {
		Field field = Foo.class.getDeclaredField("mapping");
		ParameterizedType type = (ParameterizedType) field.getGenericType();
		Assert.assertEquals("java.util.Map<java.lang.String, java.lang.String>", type.getTypeName());
		Assert.assertEquals("class java.lang.String", type.getActualTypeArguments()[0].toString());
		Assert.assertEquals("class java.lang.String", type.getActualTypeArguments()[1].toString());
		Assert.assertEquals(String.class, type.getActualTypeArguments()[0]);
		Assert.assertEquals(String.class, type.getActualTypeArguments()[1]);
		Assert.assertEquals("interface java.util.Map", type.getRawType().toString());
		Assert.assertEquals(Map.class, type.getRawType());
		Assert.assertNull(type.getOwnerType());
	}
	
	@Test
	public void test3() throws Exception {
		Field field = Foo.class.getDeclaredField("data");
		ParameterizedType type = (ParameterizedType) field.getGenericType();
		Assert.assertEquals("java.util.Map<java.lang.String, java.util.List<java.lang.String>>", type.getTypeName());
		Type subType = type.getActualTypeArguments()[1];
		Assert.assertTrue(subType instanceof ParameterizedType);
		
		// subType like method test
	}
}

GenericArrayType

/** 
 * <p>Title: GenericArrayTypeTest.java</p>  
 * <p>Description: 数组类型测试</p>  
 * @author    dengjili
 * @date      2020年7月30日  
 */
public class GenericArrayTypeTest {
	static class Foo {
		private String[] array;
		private List<String>[] list;
		private String[][][] mapping;
	}
	
	@Test
	public void test() throws Exception {
		Field field = Foo.class.getDeclaredField("array");
		Type type = field.getGenericType();
		Assert.assertTrue(type instanceof Class);
	}
	
	@Test
	public void test2() throws Exception {
		Field field = Foo.class.getDeclaredField("list");
		Type type = field.getGenericType();
		Assert.assertTrue(type instanceof GenericArrayType);
		GenericArrayType arrayType = (GenericArrayType) type;
		
		String typeName = arrayType.getTypeName();
		Assert.assertEquals("java.util.List<java.lang.String>[]", typeName);
		// 去掉一个[]符号
		Type subType = arrayType.getGenericComponentType();
		Assert.assertEquals("java.util.List<java.lang.String>", subType.toString());
		
		// subType 同ParameterizedType
	}
	
	@Test
	public void test3() throws Exception {
		// String[][][]
		Field field = Foo.class.getDeclaredField("mapping");
		Type type = field.getGenericType();
		Assert.assertTrue(type instanceof Class);
		Assert.assertEquals("java.lang.String[][][]", type.getTypeName());
		Class<?> clazz = (Class<?>) type;
		Assert.assertTrue(clazz.isArray());
		Class<?> componentType = clazz.getComponentType();
		Assert.assertEquals("java.lang.String[][]", componentType.getTypeName());
		componentType = componentType.getComponentType();
		Assert.assertEquals("java.lang.String[]", componentType.getTypeName());
		componentType = componentType.getComponentType();
		Assert.assertEquals("java.lang.String", componentType.getTypeName());
		Assert.assertFalse(componentType.isArray());
	}
}

WildcardType

/** 
 * <p>Title: WildcardTypeTest.java</p>  
 * <p>Description: 通配符类型测试</p>  
 * @author    dengjili
 * @date      2020年7月30日  
 */
public class WildcardTypeTest {
	
	static interface A {
	}
	
	static class Foo {
		private Class<? extends String> str;
		private Map<? extends A, ? super Number> map;
	}
	
	@Test
	public void test() throws Exception {
		Field field = Foo.class.getDeclaredField("str");
		Type type = field.getGenericType();
		Assert.assertTrue(type instanceof ParameterizedType);
		ParameterizedType parameterizedType = (ParameterizedType) type;
		Type subType = parameterizedType.getActualTypeArguments()[0];
		Assert.assertTrue(subType instanceof WildcardType);
		WildcardType wildcardType = (WildcardType) subType;
		String typeName = wildcardType.getTypeName();
		Assert.assertEquals("? extends java.lang.String", typeName);
		Type[] upperBounds = wildcardType.getUpperBounds();
		Type[] lowerBounds = wildcardType.getLowerBounds();
		Assert.assertEquals(1, upperBounds.length);
		Assert.assertEquals(0, lowerBounds.length);
		Assert.assertEquals(String.class, upperBounds[0]);
	}
	
	@Test
	public void test2() throws Exception {
		// Map<? extends A, ? super Number>
		Field field = Foo.class.getDeclaredField("map");
		Type type = field.getGenericType();
		Assert.assertTrue(type instanceof ParameterizedType);
		ParameterizedType parameterizedType = (ParameterizedType) type;
		Type subType1 = parameterizedType.getActualTypeArguments()[0];
		Type subType2 = parameterizedType.getActualTypeArguments()[1];
		Assert.assertTrue(subType1 instanceof WildcardType);
		Assert.assertTrue(subType2 instanceof WildcardType);
		WildcardType wildcardType1 = (WildcardType) subType1;
		WildcardType wildcardType2 = (WildcardType) subType2;
		Type[] upperBounds = wildcardType1.getUpperBounds();
		Type[] lowerBounds = wildcardType1.getLowerBounds();
		Assert.assertEquals(1, upperBounds.length);
		Assert.assertEquals(0, lowerBounds.length);
		Assert.assertEquals(A.class, upperBounds[0]);
		
		// ? super Number
		Type[] upperBounds2 = wildcardType2.getUpperBounds();
		Type[] lowerBounds2 = wildcardType2.getLowerBounds();
		Assert.assertEquals(1, upperBounds2.length);
		Assert.assertEquals(1, lowerBounds2.length);
		Assert.assertEquals(Number.class, lowerBounds2[0]);
		Assert.assertEquals(Object.class, upperBounds2[0]);
	}
}

TypeVariable

/** 
 * <p>Title: TypeVariableTest.java</p>  
 * <p>Description: 泛型类型测试</p>  
 * @author    dengjili
 * @date      2020年7月30日  
 */
public class TypeVariableTest {
	static class Foo<T> {
		private T t;
		
		<K extends Number> K test() {
			return null;
		}
	}
	
	@Test
	public void test() throws Exception {
		Field field = Foo.class.getDeclaredField("t");
		Type type = field.getGenericType();
		Assert.assertTrue(type instanceof TypeVariable);
		TypeVariable typeVariable = (TypeVariable) type;
		Type[] bounds = typeVariable.getBounds();
		Assert.assertEquals(1, bounds.length);
		Assert.assertEquals(Object.class, bounds[0]);
		Assert.assertEquals(Foo.class, typeVariable.getGenericDeclaration());
		Assert.assertEquals("T", typeVariable.getName());
	}
	
	@Test
	public void test2() throws Exception {
		Method method = Foo.class.getDeclaredMethod("test");
		Class<?> type = method.getReturnType();
		Assert.assertEquals(Number.class, type);
		TypeVariable typeVariable = (TypeVariable) method.getGenericReturnType();
		Assert.assertEquals(method, typeVariable.getGenericDeclaration());
		Assert.assertEquals("K", typeVariable.getName());
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值