JAVA类的顶层Type抽象和继承关系

    科技2022-07-21  118

    type的继承关系

    Type是java对于类型的高级抽象,是所有类型的父亲 Type的子类型用途举例参数化类型(ParameterizedType)用来描述泛型,泛型定义只能在class、construct、method上List<T>、Map<K,V>等带有参数化的对象泛型数组(GenericArrayType)描述泛型数组List<String>[] 、T[]等;注意Integer[],int[] 等不属于GenericArrayType,而属于普通类型(Class,isArray()方法返回true)类型变量(TypeVariable)描述<>里面内容,描述泛型的具体类型Class<T>中的T通配符变量(WidecardType)描述<>里面内容,描述泛型的通配符Class<?>中的?原始类型(Class)java对象的class,包括类、美剧、数组、注解Integer.class、Object.class基本类型(Class)java的8种基本类型的class基本类型的class,如 int.class

    ParameterizedType

    接口说明

    public interface ParameterizedType extends Type {}

    方法用途举例Type[] getActualTypeArguments();获取泛型<T,U>的内容,若无泛型则返回空数组对于Map<String,Integer>返回的Type[]为String和IntegerType getRawType();获取<>前面的类对于Map<String,Integer>返回的Type为MapType getOwnerType();获取<>前面的类(记为A)的拥有者,如果A是顶层类,那么此方法返回nullif this type is {@code O<T>.I<S>}, return a representation of {@code O<T>}

    用法

    public class ParameterizedTypeTest { public static class GenericType<T,U> { } public static interface GenericResult<R> { } public static class Instance<T,U,R> extends GenericType<T,U> implements GenericResult<R> { } public static void main(String[] args) { Instance<String, Double, Integer> instance = new Instance<>(); // 类型是ParameterizedType:只有一个元素GenericResult<R> Type[] types = instance.getClass().getGenericInterfaces(); // 类型是ParameterizedType:表示GenericType<T, U> Type type = instance.getClass().getGenericSuperclass(); ParameterizedType parameterizedType = (ParameterizedType) type; // 类型是TypeVariable:两个元素T, U Type[] actualTypes = parameterizedType.getActualTypeArguments(); // 类型是class : 不论GenericType是内部类,还是静态内部类,其父类都是Test.class Type ownerType = parameterizedType.getOwnerType(); // 类型是class : GenericType Type rawType = parameterizedType.getRawType(); // GenericType.toString() : Test$GenericType<T, U> String typeName = parameterizedType.getTypeName(); // 类型是class : class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl Class<? extends ParameterizedType> clazz = parameterizedType.getClass(); } }

    GenericArrayType

    接口说明

    public interface GenericArrayType extends Type {}

    方法用途举例Type getGenericComponentType();获取数组的门面类型List<?>[]得到的是List<?>

    用法

    @FieldNameConstants public class GenericArrayTypeTest<T> { private List<String>[] stringListArray; private List<?>[] noBoundListArray; private T[] tArray; private int[] intArray; public static void main(String[] args) { handle(GenericArrayTypeTest.FIELD_STRING_LIST_ARRAY); handle(GenericArrayTypeTest.FIELD_NO_BOUND_LIST_ARRAY); handle(GenericArrayTypeTest.FIELD_T_ARRAY); handle(GenericArrayTypeTest.FIELD_INT_ARRAY); } @SneakyThrows private static void handle(String fieldName) { Field field = GenericArrayTypeTest.class.getDeclaredField(fieldName); /** * <ul> * <li>stringListArray : 类型GenericArrayType : List<String>[]是泛型数组</li> * <li>noBoundListArray : 类型GenericArrayType : List<?>[]是泛型数组</li> * <li>tArray : 类型GenericArrayType : T[]是泛型数组</li> * <li>intArray : 不是泛型数组, 解析报错</li> * </ul> */ Type genericType = field.getGenericType(); GenericArrayType genericArrayType = (GenericArrayType) genericType; /** * <ul> * <li>stringListArray : 类型是ParameterizedType : List<String></li> * <li>noBoundListArray : 类型是ParameterizedType : List<?></li> * <li>tArray : 类型是类型TypeVariable : T</li> * <li>intArray : 不是泛型数组, 解析报错</li> * </ul> */ Type genericComponentType = genericArrayType.getGenericComponentType(); System.out.println(genericComponentType); // java.util.List<java.lang.String> } }

    TypeVariable

    接口说明

    public interface TypeVariable extends Type, AnnotatedElement {}

    方法用途举例Type[] getBounds();获取泛型的上界,无显示定义extends定义上界,则默认上界为ObjectD getGenericDeclaration();Java中可以声明泛型变量的地方有三个class,contructor和method。此方法就是获取到声明类型变量的语法元素(指向哪个class,哪个class的哪个构造方法,哪个class的哪个方法)String getName();获取名称,即K,VAnnotatedType[] getAnnotatedBounds();

    用法

    // 类型TypeVariable : 返回A,B TypeVariable<Class<GenericType>>[] typeVariables = GenericType.class.getTypeParameters(); // 类型Class : Serializable Type[] aBoundType = typeVariables[0].getBounds(); // 类型Class : Object Type[] bBoundType = typeVariables[1].getBounds(); // 类型String : A String aName = typeVariables[0].getTypeName(); // 类型String : B String bName = typeVariables[1].getTypeName(); // 类型Class : 定义泛型A,B的类TypeVariableTest$GenericType typeVariables[0].getGenericDeclaration(); // 类型Class : 定义泛型A,B的类TypeVariableTest$GenericType typeVariables[1].getGenericDeclaration();

    WildcardType

    接口说明

    public interface TypeVariable extends Type, AnnotatedElement {}

    方法用途举例Type[] getUpperBounds();获取?的上界,默认上界为ObjectType[] getLowerBounds();获取?的下界。若无下界则返回空数组

    用法

    public static class GenericType { public String print(List<? extends String> aList, List<? super Integer> bList) throws Exception { return aList.toString(); } @SneakyThrows public static void main(String[] args) { // 获取 String print(List<? extends String> aList, List<? super Integer> bList) throws Exception Method method = GenericType.class.getDeclaredMethod("print", List.class, List.class); // 获取形参 List<? extends String> aList, List<? super Integer> bList Type[] genericParameterTypes = method.getGenericParameterTypes(); // 获取泛型通配符 ? extends String Type aListWildcard = ((ParameterizedType) genericParameterTypes[0]).getActualTypeArguments()[0]; WildcardType aListWildcardType = (WildcardType) aListWildcard; // 打印[class java.lang.String] System.out.println(Arrays.toString(aListWildcardType.getUpperBounds())); // 打印[] System.out.println(Arrays.toString(aListWildcardType.getLowerBounds())); // 获取泛型通配符? super Integer Type bListWildcard = ((ParameterizedType) genericParameterTypes[1]).getActualTypeArguments()[0]; WildcardType bListWildcardType = (WildcardType) bListWildcard; // 打印[class java.lang.Object] System.out.println(Arrays.toString(bListWildcardType.getUpperBounds())); // 打印[class java.lang.Integer] System.out.println(Arrays.toString(bListWildcardType.getLowerBounds())); } }

    Class

    方法说明

    类和对象的关系判断

    instanceof 用法 Object instanceof Classinstanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false左边不能是基础类型null用instanceof跟任何类型比较时都是false Class.isInstanceof(Object) 与instanceof功能等价 Class.isAssignableFrom(Class) 类和类的关系判断,如果左侧是右侧的父类或本类,则返回true public static class Father { } public static class Son extends Father { } public static void main(String[] args) { Father father = new Father(); Son son = new Son(); System.out.println(father instanceof Father);// true System.out.println(son instanceof Father);// true System.out.println(Father.class.isInstance(father));// true System.out.println(Father.class.isInstance(son));// true System.out.println(Father.class.isAssignableFrom(Father.class));// true System.out.println(Father.class.isAssignableFrom(Son.class));// true System.out.println(Son.class.isAssignableFrom(Father.class));// false }

    获取名称

    getName() 获取全路径类名 public String getName() { String name = this.name; if (name == null) this.name = name = getName0(); return name; } private native String getName0();

    如果是基本类型,则返回byte、void等 如果是对象类型,则返回全路径(包名+类名) 如果是数组类型,则按照下面的格式返回 2. getTypeName() 和getName()区别在于数组类型,对数组类型的展示方法进行优化,转换符合java语法的形式

    public String getTypeName() { if (isArray()) { try { Class<?> cl = this; int dimensions = 0; while (cl.isArray()) { dimensions++; cl = cl.getComponentType(); } StringBuilder sb = new StringBuilder(); sb.append(cl.getName()); for (in t i = 0; i < dimensions; i++) { sb.append("[]"); } return sb.toString(); } catch (Throwable e) { /*FALLTHRU*/ } } return getName(); } System.out.println((new Object[3]).getClass().getName());//[Ljava.lang.Object; System.out.println((new Object[3]).getClass().getTypeName());//java.lang.Object[] System.out.println((new int[3][4][5][6][7][8][9]).getClass().getName());//[[[[[[[I System.out.println((new int[3][4][5][6][7][8][9]).getClass().getTypeName());//int[][][][][][][] getCanonicalName() 和getTypeName()区别在于内部类,对于普通内部类,返回符合java语言书写规范的全路径。 对于匿名内部类则返回null public class ClassTest { public static class Father { } public static class Son extends Father { } public static void main(String[] args) { // 普通类 Father father = new Father(); System.out.println("----普通类----"); System.out.println(father.getClass().getName());//ClassTest$Father System.out.println(father.getClass().getTypeName());//ClassTest$Father System.out.println(father.getClass().getCanonicalName());//ClassTest.Father System.out.println(father.getClass().getSimpleName()); } } getSimpleName() 获取简单类名,在getCanonicalName()的基础上,去掉package路径

    对于不同类型,以上方法的返回值

    public class ClassTest { public static class Father { } public static void main(String[] args) { // 普通类 Father father = new Father(); System.out.println("----普通类----"); System.out.println(father.getClass().getName());//ClassTest$Father System.out.println(father.getClass().getTypeName());//ClassTest$Father System.out.println(father.getClass().getCanonicalName());//ClassTest.Father System.out.println(father.getClass().getSimpleName());//Father // 匿名类 Father inner = new Father(){}; System.out.println("----内部类----"); System.out.println(inner.getClass().getName());//ClassTest$1 System.out.println(inner.getClass().getTypeName());//ClassTest$1 System.out.println(inner.getClass().getCanonicalName());//null System.out.println(inner.getClass().getSimpleName());//空字符串 // 数组 Father[] array = new Father[1]; System.out.println("----对象数组类----"); System.out.println(array.getClass().getName());//[LClassTest$Father; System.out.println(array.getClass().getTypeName());//ClassTest$Father[] System.out.println(array.getClass().getCanonicalName());//ClassTest.Father[] System.out.println(array.getClass().getSimpleName());//Father[] // 基本类型数组 int[] rawArray = new int[1]; System.out.println("----基本类型数组类----"); System.out.println(rawArray.getClass().getName());//[I System.out.println(rawArray.getClass().getTypeName());//int[] System.out.println(rawArray.getClass().getCanonicalName());//int[] System.out.println(rawArray.getClass().getSimpleName());//int[] } } class.getDeclaringClass()和field.getDeclaringClass()方法的用途 @FieldNameConstants public class ClassTest { private Father father; public ClassTest() { this.father = new Father(); } public static class Father { } @SneakyThrows public static void main(String[] args) { ClassTest classTest = new ClassTest(); // class ClassTest System.out.println(classTest.father.getClass().getDeclaringClass()); // class ClassTest Field field = ClassTest.class.getDeclaredField(ClassTest.FIELD_FATHER); System.out.println(field.getDeclaringClass()); } } 获取class的注解信息 class注解操作(AnnotatedElement) Spring注解工具类AnnotatedElementUtils和AnnotationUtils

    参考

    Spring工具类

    Processed: 0.012, SQL: 8