public interface Type
是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
使用junit断言,下面例子都可以直接运行通过
/**
* Title: ParameterizedTypeTest.java
* Description: 参数化类型测试
* @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" , 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>" , type.getTypeName());
Type subType = type.getActualTypeArguments()[1];
Assert.assertTrue(subType instanceof ParameterizedType);
// subType like method test
}
}
/**
* Title: GenericArrayTypeTest.java
* Description: 数组类型测试
* @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[]" , typeName);
// 去掉一个[]符号
Type subType = arrayType.getGenericComponentType();
Assert.assertEquals("java.util.List" , 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());
}
}
/**
* Title: WildcardTypeTest.java
* Description: 通配符类型测试
* @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]);
}
}
/**
* Title: TypeVariableTest.java
* Description: 泛型类型测试
* @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());
}
}