1. Comprensión sencilla de los genéricos
Los genéricos son una nueva característica de Java SE 1.5. La esencia de los genéricos es un tipo parametrizado, lo que significa que el tipo de datos sobre el que se opera se especifica como un parámetro. El punto popular es "tipo variable". Las variables de este tipo se pueden utilizar en la creación de clases, interfaces y métodos.
La forma más fácil de entender los genéricos de Java es pensar en ellos como una sintaxis conveniente que le ahorra algunas operaciones de conversión de Java:
Copie el código de la siguiente manera: List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);
El código anterior se expresa muy claramente: box es una Lista que contiene objetos de Apple. El método get devuelve una instancia de objeto Apple y no se requiere conversión de tipo en este proceso. Sin genéricos, el código anterior debe escribirse así:
Copie el código de la siguiente manera: Apple apple = (Apple)box.get(0);
2. La vergüenza de los genéricos
La mayor ventaja de los genéricos es que proporcionan seguridad de tipo de programa y son compatibles con versiones anteriores, pero también tienen un punto incómodo, que es que el tipo de genérico debe especificarse cada vez que se define. No solo parece un poco detallado. No es necesario especificarlo explícitamente, pero muchos programadores no están familiarizados con los genéricos, por lo que a menudo no pueden proporcionar los parámetros de tipo correctos. Ahora el compilador puede inferir automáticamente los tipos de parámetros de los genéricos, lo que puede reducir este tipo de situaciones y mejorar el código. legibilidad.
3. Mejoras en la inferencia de tipos genéricos en Java 7
En versiones anteriores, cuando se usaban tipos genéricos, era necesario agregar el tipo genérico en ambos lados al declarar y asignar valores. Por ejemplo:
Copie el código de la siguiente manera: Map<String, String> myMap = new HashMap<String, String>();
Puede pensar: ya especifiqué el tipo de parámetro al declarar la variable, ¿por qué necesito especificarlo nuevamente al inicializar el objeto? Afortunadamente, en Java SE 7, este método se ha mejorado y ahora puede declarar y asignar valores utilizando las siguientes declaraciones:
Copie el código de la siguiente manera: Map<String, String> myMap = new HashMap<>() //Preste atención al "<>" al final;
En esta declaración, el compilador inferirá automáticamente el tipo genérico al crear una instancia de HashMap en función del tipo genérico cuando se declara la variable. Nuevamente, asegúrese de prestar atención al "<>" después del nuevo HashMap. Solo agregar este "<>" significa inferencia de tipo automática. De lo contrario, es un HashMap de tipo no genérico y se proporcionará cuando se use el compilador. compilar el código fuente.
Sin embargo: la inferencia de tipos de Java SE 7 al crear instancias genéricas es limitada: solo si el tipo parametrizado del constructor se declara explícitamente en el contexto, se puede utilizar la inferencia de tipos; de lo contrario, no funcionará. Por ejemplo: el siguiente ejemplo no se puede compilar correctamente en Java 7 (pero ahora se puede compilar en Java 8, porque el tipo de genérico se infiere automáticamente en función de los parámetros del método):
Copie el código de código de la siguiente manera:
Lista<Cadena> lista = nueva ArrayList<>();
list.add("A");// Dado que addAll espera un parámetro de tipo Collection<? extends String>, la siguiente declaración no puede pasar
lista.addAll(new ArrayList<>());
4. Mejoras en la inferencia de tipos genéricos en Java 8
Hay dos tipos principales de inferencia de tipos de destino para genéricos en Java 8:
1. Admite la inferencia de tipos de objetivos genéricos a través del contexto del método.
2. Admite pasar inferencia de tipos genéricos al último método en la cadena de llamadas al método.
Veamos un ejemplo del sitio web oficial:
Copie el código de código de la siguiente manera:
Lista de clases<E> {
estática <Z> Lista<Z> nil() { ... };
static <Z> Lista<Z> cons(Z cabeza, Lista<Z> cola) {...};
mi cabeza() {...}
}
Según las características de JEP101, podemos escribir así al llamar al método anterior
Copie el código de código de la siguiente manera:
// Inferir automáticamente el tipo de genérico a través del parámetro de destino de la asignación del método
Lista<Cadena> l = Lista.nil();
//En lugar del tipo especificado mostrado
//Lista<Cadena> l = Lista.<Cadena>nil();
// Inferir el tipo de genérico a través del tipo de parámetro del método anterior
Lista.cons(42, Lista.nil());
//En lugar del tipo especificado mostrado
//List.cons(42, List.<Integer>nil());
5. Resumen
Lo anterior es el contenido característico de JEP101. Como representante de los lenguajes estáticos, se puede decir que Java tiene un sistema de tipos rico. El problema de la conversión entre tipos preocupa a todos los programadores de Java. La inferencia automática de tipos a través del compilador puede aliviar ligeramente el problema de la conversión de tipos demasiado compleja. Aunque es una pequeña mejora, definitivamente tendrá un gran impacto en nuestros programadores que escriben código todos los días. Al menos se sentirán más felices ~~ Quizás en Java 9 obtengamos una var de tipo universal, como js o algunos lenguajes dinámicos. de scala son así^_^