(1). Tipos de interfaz relacionados con reflexión + genéricos.
java.lang.reflect.Type: interfaz principal común para todos los tipos en el lenguaje Java
java.lang.reflect.ParameterizedType
java.lang.reflect.GenericArrayType
java.lang.reflect.WildcardType
1. Escriba la subinterfaz directa
Cuatro tipos de interfaces: ParameterizedType, GenericArrayType, TypeVariable y WildcardType
ParameterizedType: representa un tipo parametrizado, como Colección
GenericArrayType: representa un tipo de matriz cuyo tipo de elemento es un tipo parametrizado o tipo variable
TypeVariable: es la interfaz principal común para varios tipos de variables.
WildcardType: representa una expresión de tipo comodín, como ?, ? extiende Número, ? super Integer [comodín es una palabra: es "comodín"]
2. El tipo implementa directamente subclases: clase clase
3. interfaz java.lang.reflect.Type
Todos los tipos de Tipo se refieren a: tipos sin formato (tipos sin formato) [correspondientes a Clase], tipos parametrizados (tipos parametrizados) [correspondientes a ParameterizedType], tipos de matriz (tipos de matriz) [correspondientes a GenericArrayType], variables de tipo (variables de tipo) [ correspondiente a TypeVariable], tipos de datos básicos (tipos primitivos) [todavía correspondiente a Clase]
4. Interfaz java.lang.reflect.ParameterizedType
El significado del tipo de interfaz ParameterizedType
Representa un tipo parametrizado. Por ejemplo: un tipo parametrizado como Mapa
Obtenga el tipo real en tipo parametrizado <>
Declaración del código fuente: Type[] getActualTypeArguments();
[Nota] No importa cuántos niveles de anidamiento <> haya en <>, este método solo elimina el <> más externo y el contenido restante se utiliza como valor de retorno de este método.
método público estático E IV (
ListaMatriz> al1,
Lista de matrices al2,
Lista de matrices al3,
ArrayListextends Número> al4,
ArrayList al5){}
Entonces cada uno de sus parámetros es generalmente de tipo paramétrico.
{1}. Para ArrayList>, después de regresar a través de getActualTypeArguments (), después de eliminar el <> más externo, el tipo restante es ArrayList. Por lo tanto, el tipo de retorno para este parámetro es ParameterizedType.
{2}. Para ArrayList, después de regresar a través de getActualTypeArguments (), después de eliminar el <> más externo, el tipo restante es E. Por lo tanto, el tipo de retorno para este parámetro es TypeVariable.
{3}. Para ArrayList, después de regresar a través de getActualTypeArguments (), después de eliminar el <> más externo, el tipo restante es String. Por lo tanto, el tipo de retorno para este parámetro es Clase.
{4}. Para ArrayListextends Number>, después de regresar a través de getActualTypeArguments (), después de eliminar el <> más externo, el tipo restante es ExtendsNumber. Por lo tanto, el tipo de retorno para este parámetro es WildcardType.
{5}. Para ArrayList, después de regresar a través de getActualTypeArguments (), después de eliminar el <> más externo, el tipo restante es E []. Por lo tanto, el tipo de retorno para este parámetro es GenericArrayType.
Por lo tanto, es posible obtener parámetros reales de varios tipos, por lo que, en aras de la unificación, se utiliza la matriz de clase principal directa Type[] para la recepción.
4. Interfaz java.lang.reflect.GenericArrayType
El significado del tipo de interfaz GenericArrayType
Representa un tipo de matriz genérico. Por ejemplo: método void(ArrayList[] al){…}
[Nota] <> no puede aparecer en la inicialización de la matriz, es decir, <> no puede aparecer después de la nueva matriz; de lo contrario, javac no pasará. Pero está completamente bien como variable de referencia o parámetro de un método.
Obtener el tipo de elementos en una matriz genérica
Declaración del código fuente: Escriba getGenericComponentType();
[Nota] No importa cuántos [] se yuxtapongan de izquierda a derecha, este método solo elimina el [] más a la derecha y el contenido restante se utiliza como valor de retorno de este método.
¿Por qué el tipo de valor de retorno es Tipo?
método público estático E V(String[] p1,E[] p2,ArrayList[] p3,E[][] p4){}{1}. Para String [], después de regresar a través de getComponentType (), después de eliminar el [] más a la derecha, el tipo restante es String. Por lo tanto, el tipo de retorno para este parámetro es Clase
{2}. Para E [], después de regresar a través de getComponentType (), después de eliminar el [] más a la derecha, el tipo restante es E. Por lo tanto, el tipo de retorno para este parámetro es TypeVariable
{3}. Para ArrayList [], después de regresar a través de getComponentType (), después de eliminar el [] más a la derecha, el tipo restante es ArrayList. Por lo tanto, el tipo de retorno para este parámetro es ParameterizedType
{4}. Para E [] [], después de regresar a través de getComponentType (), después de eliminar el [] más a la derecha, el tipo restante es E []. Por lo tanto, el tipo de retorno para este parámetro es GenericArrayType.
5. Interfaz java.lang.reflect.GenericArrayType
El significado del tipo de interfaz TypeVariable
Representa parámetros de tipo o también llamados variables de tipo. Por ejemplo: E en el método void (E e){} es la variable de tipo
Obtiene el tipo de límite superior genérico de una variable de tipo
Declaración del código fuente: Type[] getActualTypeArguments();
[Nota] Este es solo el límite superior. La razón es que las variables de tipo solo pueden usar extensiones para limitar (múltiples) límites cuando están definidas. Super no se puede utilizar; de lo contrario, la compilación no se realizará. Al mismo tiempo, extiende proporciona el límite superior de las variables de tipo.
¿Por qué el tipo de retorno es una matriz? Debido a que las variables de tipo pueden calificarse con múltiples límites superiores mediante &, existen múltiples límites superiores, por lo que el tipo de valor de retorno es el tipo de matriz [].
Por ejemplo el siguiente método:
public static extiende Map& Cloneable&Serializable> E métodoVI(E e){…}El primer límite superior de E es Map, que es un tipo ParameterizedType
El segundo límite superior de E es Clonable, que es de tipo Clase
Por lo tanto, para la unificación, el tipo de elemento de la matriz de valores de retorno es Tipo
6. Interfaz java.lang.reflect.WildcardType
El significado del tipo de interfaz WildcardType
Una expresión que representa un tipo comodín.
Por ejemplo, ? extiende Número en void printColl(ArrayListal);
[Nota] Según los comentarios de la API anterior: en esta etapa, las expresiones comodín solo aceptan un límite superior o un límite inferior, que es diferente de los múltiples límites superiores que se pueden especificar al definir variables de tipo. Pero la API dice que para mantener la escalabilidad, el tipo de valor de retorno aquí está escrito en forma de matriz. De hecho, el tamaño de la matriz devuelta ahora es 1
Obtiene el tipo de límite superior genérico de un objeto de expresión comodín
Declaración del código fuente: Escriba[] getUpperBounds();
[Nota] Como se mencionó anteriormente, el tamaño de la matriz en Tipo [] devuelta en esta etapa es 1. Escrito como Tipo[] es una extensión para la actualización del idioma.
Por ejemplo el siguiente método:
{1}. voidprintColl público estático (ArrayListextends ArrayList> al){}
La expresión comodín es: ? extendsArrayList, de modo que extend va seguido del límite superior de ?, y este límite superior es el tipo ParameterizedType.
{2}.
La expresión comodín es: ? extiende E, de modo que extend va seguido del límite superior de ?, y este límite superior es del tipo TypeVariable
{3}.public static voidprintColl(ArrayListextends E[]> al){}
La expresión comodín es: ? extiende E[], de modo que extend va seguido del límite superior de ?, y este límite superior es del tipo GenericArrayType.
{4}.public static voidprintColl(ArrayListextends Number> al){}
La expresión comodín es: ? extiende Número, de modo que a extensión le sigue el límite superior de ?, y este límite superior es el tipo Clase
Finalmente unificado en Tipo como tipo de elemento de la matriz.
7. El origen de Type y sus subinterfaces
1. Tipos antes de la aparición de los genéricos.
Cuando no hay genéricos, sólo existen los llamados tipos primitivos. En este momento, todos los tipos primitivos se abstraen a través de la clase de archivo de código de bytes Class. Un objeto concreto de la clase Class representa un tipo primitivo específico.
2. Tipos tras la aparición de los genéricos.
Tras la aparición de los genéricos, se ampliaron los tipos de datos. Desde solo los tipos primitivos, se han ampliado los tipos parametrizados, los tipos de variables de tipo, los tipos parametrizados calificados genéricos (incluidos los comodines + expresiones calificadas como comodines) y los tipos de matriz genéricos.
3. La razón por la que los tipos relacionados con genéricos no se pueden unificar con los tipos originales en Clase
[1]. [Causa del borrado genérico]
Originalmente, los tipos recién generados + tipos primitivos deberían unificarse en sus respectivos objetos de tipo de archivo de código de bytes. Pero dado que los genéricos no eran originalmente un ingrediente en Java. Si realmente se agregan genéricos, implica modificar el conjunto de instrucciones JVM, lo cual es muy fatal.
[2]. [Cómo introducir genéricos en Java]
Para aprovechar los genéricos sin introducirlos realmente, Java utiliza un mecanismo de borrado genérico para introducir genéricos. Los genéricos en Java solo los utiliza el compilador javac para garantizar la seguridad de los datos y evitar el problema de la conversión de tipos forzada. Sin embargo, una vez completada la compilación, se borran todos los tipos relacionados con los genéricos.
[3]. [La clase no puede expresar tipos relacionados con genéricos]
Por lo tanto, los tipos parametrizados relacionados con genéricos, tipos de variables de tipo, tipos parametrizados calificados genéricos (incluidos comodines + expresiones calificadas como comodines) y tipos de matrices genéricos se devuelven a sus formas originales y se almacenan en el archivo de código de bytes. Todos son tipos originales. después de que se hayan borrado los genéricos y no haya ningún archivo de código de bytes coherente con su propio tipo. Por lo tanto, los tipos recientemente ampliados relacionados con genéricos no se pueden unificar en la clase Clase.
(4). Representación de tipos relacionados con genéricos en Java.
Para operar estos tipos a través de la reflexión para satisfacer las necesidades del desarrollo real, Java agregó ParameterizedType, GenericArrayType, TypeVariable y WildcardType para representar tipos que no se pueden clasificar en la clase Class pero que tienen el mismo nombre que el tipo original.
(5) Introducción de tipo: tipos unificadores relacionados con clases genéricas y tipos primitivos.
[Razón para introducir el tipo]
Para la escalabilidad del programa, finalmente se introdujo la interfaz Type como la interfaz principal general para Class, ParameterizedType, GenericArrayType, TypeVariable y WildcardType. De esta manera, el parámetro de tipo Tipo acepta los parámetros reales de los cinco subtipos anteriores o el tipo de valor de retorno es el parámetro de tipo Tipo.
[La razón por la que no hay ningún método en la interfaz Tipo]
Como se puede ver en lo anterior, la aparición de Tipo solo desempeña el papel de mejorar la escalabilidad del programa a través del polimorfismo y no tiene ningún otro efecto. Por lo tanto, no hay métodos en el código fuente de la interfaz Type.