Java--Reflection--Type Interface/Subinterface/Subclass--Use/Usage/Application/Instance/Sample/Practice

Original web address: Java--Reflection--Type Interface/Subinterface/Subclass--Usage/Usage/Application/Instance/Example/Practice_IT Cutting-edge Blog-CSDN Blog

Other web addresses

Java Type Class and its Subclasses - Short Book
java Type and its subclasses Introducing _qq_37718687's Blog-CSDN Blog

brief introduction

Explain

Type is an interface provided in the java reflection mechanism to represent all types of interfaces in java. They include primitive types, parameterized types, array types, type variables, and basic types. (This is written in the comment to the Type source code.)

  • Original type: A java class in general, implemented by a class class class
  • Parameterized type: Implementation class for the ParameterizedType interface
  • Array type: Implementation class for the GenericArrayType interface
  • Type variables: Implementation classes for the TypeVariable interface
  • Basic types: java basic types such as int, float, etc. (Actually, they are also class es)

Type classes can be seen in almost all frameworks, especially where proxy and reflection are involved. A good understanding of Type classes will also be beneficial for future frameworks encapsulation and source code interpretation.

Type Interface Source

package java.lang.reflect;

/**
 * Type is the common superinterface for all types in the Java
 * programming language. These include raw types, parameterized types,
 * array types, type variables and primitive types.
 *
 * @since 1.5
 */
public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}

Subinterface/Subclass of Type

The subinterface/subclass of Type is as follows:

Example

Below I will only use fields for examples. Methods and classes are the same usage.

Class

Class has so many methods, after all, it contains all the information about the class. Here you can see more: Java--Reflection--Introduction/Use/Usage/Example/Practice/Application_IT Cutting-edge Blog-CSDN Blog

Here's a simple example.

package com.example.a;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

class ClassTest{
    private String userName;

    public void sayHello() {
        System.out.println("Hello");
    }
}

public class Demo {
    public static void main(String[] args) {
        Field[] declaredFields = ClassTest.class.getDeclaredFields();
        Method[] declaredMethods = ClassTest.class.getDeclaredMethods();

        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }

        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
    }
}

ParameterizedType

A parameterized type, that is, a type with generics; for example, List<T>, Map<K, V>.

Source code

public interface ParameterizedType extends Type {
    //Gets a parameterized type parameter. For example, Map <K, V> is a K/V array;
    Type[] getActualTypeArguments();
    
    //Gets the original type, generic type. For example, List <T> is List
    Type getRawType();
    
    //If it is an internal class, get the external class that has the internal class. For example: Map.Entry<K, V>, Map
    Type getOwnerType();
}

Example

package com.example.a;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

class ParameterizedTypeTest<T> {
    private List<T> tList;
    private Map<String, Integer> stringIntegerMap;
}

public class Demo {
    public static void main(String[] args) {
        Field[] declaredFields = ParameterizedTypeTest.class.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // Get the type of field
            Type type = declaredField.getGenericType();
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                // Parameter type name. Output: List<T>and Map<String, Integer>
                System.out.println("typeName:  " + parameterizedType.getTypeName());
                // Parent. Null everywhere
                System.out.println("ownerType: " + parameterizedType.getOwnerType());
                // Original type. Output: interface java.util.List/Map
                System.out.println("rawType:   " + parameterizedType.getRawType());
                // The actual type of parameter. Output: T and java.lang.String/Integer
                for (Type arguments : parameterizedType.getActualTypeArguments()) {
                    System.out.println(arguments.getTypeName());
                }
            }
            System.out.println("----------------------------------");
        }
    }
}

Run Results

typeName:  java.util.List<T>
ownerType: null
rawType:   interface java.util.List
T
----------------------------------
typeName:  java.util.Map<java.lang.String, java.lang.Integer>
ownerType: null
rawType:   interface java.util.Map
java.lang.String
java.lang.Integer
----------------------------------

TypeVariable

Type variables, that is, variables in generics; for example, variables such as T, K, V, etc., can represent any class;

TypeVariable s represent variables in a generic, while ParameterizedType s represent the entire generic.

Source code

public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
    //Gets the upper limit of the variable of this type, which is the value to the right of the extension in the generic type;
    //  For example, List <T extends Number>, Number is the upper limit of the type variable T;
    Type[] getBounds();

    //Gets the variable entity that declares this type
    D getGenericDeclaration();

    String getName();

    AnnotatedType[] getAnnotatedBounds();
}

Example

package com.example.a;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
import java.util.Map;

class TypeVariableTest<T> {
    private List<Integer> integerList;
    private Map<String, T> stringTMap;
}

public class Demo {
    public static void main(String[] args) {
        Class<TypeVariableTest> clazz = TypeVariableTest.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Type type = declaredField.getGenericType();
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType)type;
                for (Type type1 : parameterizedType.getActualTypeArguments()) {
                    if (type1 instanceof TypeVariable) {
                        TypeVariable typeVariable = (TypeVariable) type1;
                        System.out.println("Field name:            " + declaredField.getName());
                        System.out.println("typeName:           " + typeVariable.getTypeName());
                        System.out.println("genericDeclaration: " +
                                typeVariable.getGenericDeclaration());
                    }
                }
            }
        }
    }
}

results of enforcement

Field name:            stringTMap
typeName:           T
genericDeclaration: class com.example.a.TypeVariableTest

You can see that after filtering the code, only T is obtained.

GenericArrayType

brief introduction

Generic array type, used to describe arrays of ParameterizedType, TypeVariable type; for example, List <T>[], T[], List <Integer>[], etc. String [], int [] is not included.

Source code

public interface GenericArrayType extends Type {
    //You can get the type before the array. For example, List <String>[] is List <String>
    Type getGenericComponentType();
}

Example

package com.example.a;

import java.lang.reflect.*;
import java.util.List;

class TypeVariableTest<T> {
    private T[] ts;
    private Integer[] integers;
    private List<Integer>[] integerList;
    private List<T>[] tLists;
}

public class Demo {
    public static void main(String[] args) {
        Class<TypeVariableTest> clazz = TypeVariableTest.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Type type = declaredField.getGenericType();
            if (type instanceof GenericArrayType) {
                GenericArrayType genericArrayType = (GenericArrayType)type;
                System.out.println("Field name:              " + declaredField.getName());
                System.out.println("typeName:             " +
                        genericArrayType.getTypeName());
                System.out.println("genericComponentType: " +
                        genericArrayType.getGenericComponentType());
            }
            System.out.println("------------------------------------------");
        }
    }
}

results of enforcement

Field name:              ts
typeName:             T[]
genericComponentType: T
------------------------------------------
------------------------------------------
Field name:              integerList
typeName:             java.util.List<java.lang.Integer>[]
genericComponentType: java.util.List<java.lang.Integer>
------------------------------------------
Field name:              tLists
typeName:             java.util.List<T>[]
genericComponentType: java.util.List<T>
------------------------------------------

Visible: Integer[] is not a GenericArrayType

WildType

brief introduction

Generic expressions (wildcard expressions). For example:?extend Number,?super Integer.

WildcardType is a subinterface of Type, but it is not one of the Java types.

Source code

public interface WildcardType extends Type {
    // Get the upper boundary. For example: List<?Extends Number>, or Number
    Type[] getUpperBounds();

    // Get the lower boundary. For example: List<?Sup String>, String
    Type[] getLowerBounds();
}

Instances

package com.example.a;

import java.lang.reflect.*;
import java.util.Arrays;
import java.util.List;

class TypeVariableTest {
    private List<? extends Integer> integerList;
}

public class Demo {
    public static void main(String[] args) {
        Class<TypeVariableTest> clazz = TypeVariableTest.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Type type = declaredField.getGenericType();
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                Type[] typeArguments = parameterizedType.getActualTypeArguments();
                System.out.println("Field name:     " + declaredField.getName());
                for (Type type1 : typeArguments) {
                    if (type1 instanceof WildcardType) {
                        WildcardType wildcardType = (WildcardType) type1;
                        System.out.println("typeName:    " + wildcardType.getTypeName());
                        System.out.println("upperBounds: " +
                                Arrays.toString(wildcardType.getUpperBounds()));
                    }
                }
            }
        }
    }
}

results of enforcement

Field name:     integerList
typeName:    ? extends java.lang.Integer
upperBounds: [class java.lang.Integer]

Application of Framework to Type

Mybatis

The typeClass method in org.apache.ibatis.reflection.Reflector converts a Type object to a Class object.

private Class<?> typeToClass(Type src) {
    Class<?> result = null;
    // Cast src directly if it is an instance of Class type
    if (src instanceof Class) {
        result = (Class<?>) src;
    // If src is a parameter type, get its original type Class object;
    } else if (src instanceof ParameterizedType) {
        result = (Class<?>) ((ParameterizedType) src).getRawType();
    // If src is an array generic type, case-by-case processing
    } else if (src instanceof GenericArrayType) {
        Type componentType = ((GenericArrayType) src).getGenericComponentType();
        if (componentType instanceof Class) {
            result = Array.newInstance((Class<?>) componentType, 0).getClass();
        } else {
            Class<?> componentClass = typeToClass(componentType);
            result = Array.newInstance(componentClass, 0).getClass();
        }
    }
    if (result == null) {
        result = Object.class;
    }
    return result;
}

Tags: Java

Posted on Sat, 25 Sep 2021 12:08:47 -0400 by kelliethile