Si tuviera que decirle directamente qué son los genéricos, realmente no podría. Aquí hay una pregunta:
Defina una clase de punto de coordenadas que pueda guardar varios tipos de datos, como números enteros, tipos de punto flotante y tipos de cadenas.
Dado que el tipo de variable es incierto al principio, es fácil pensar en utilizar la clase principal de todos los tipos, es decir, la clase Objeto.
No más tonterías, usa código para reflejarlo
Ejemplo 1: utilizar un objeto para implementar una entrada de tipo de datos incierto
//Utiliza objeto para representar tipos inciertos
Punto público (Objeto x, Objeto y) {
this.setX(x);
this.setY(y);
}
conjunto vacío públicoX (Objeto x) {
esto.x = x;
}
objeto público getX() {
devolver x;
}
conjunto vacío públicoY (Objeto y) {
esto.y = y;
}
objeto público getY() {
devolver y;
}
}
//clase de prueba
Demostración de clase pública {
público estático vacío principal (String [] argumentos) {
System.out.println("Utilice números de punto flotante para representar coordenadas: ");
Punto p = nuevo Punto(12.23,23.21);
// Aquí, la clase Objeto se convierte a la clase Doble y luego se desempaqueta automáticamente. Los dos siguientes son iguales.
System.out.println("Coordenadas X" + (Doble)p.getX());
System.out.println("Coordenadas Y" + (Doble)p.getY());
System.out.println();
System.out.println("Usar números enteros para representar coordenadas: ");
Punto p2 = nuevo Punto(12, 23);
System.out.println("Coordenadas de X" + (Entero)p2.getX());
System.out.println("Coordenadas Y" + (Entero)p2.getY());
System.out.println();
System.out.println("Representando coordenadas como una cadena: ");
Punto p3 = nuevo punto ("29 grados de latitud norte", "113 grados de longitud este");
System.out.println("Coordenadas X" + (String)p3.getX());
System.out.println("Coordenadas Y" + (String)p3.getY());
}
}
Debe comprender claramente qué tipo está transmitiendo y luego bajarlo antes de poder usarlo.
Aunque esto satisface la demanda, también implica un factor de inseguridad. ¿Por qué se dice que está implícito?
Por ejemplo, usamos el nuevo Punto (12.23, "29 grados de latitud norte") para construir un objeto Punto
Luego use (Doble) para transformarlo hacia abajo. ¿Cuál será el resultado?
Sí, la compilación pasará, pero una vez ejecutada, se producirá una excepción de conversión de tipo.
También es muy sencillo evitar excepciones de conversión de clases. Simplemente reemplace la declaración de Objeto con una declaración de tipo fijo (como: Cadena x, Cadena y), para que se informe un error durante la compilación.
Entonces podrás encontrar los errores y hacer correcciones.
Pero entonces no podremos satisfacer la demanda.
Para evitar riesgos de seguridad y sustituir varios tipos de datos, esas personas talentosas introdujeron el concepto de genéricos en JDK1.5.
Veamos cómo reescribir el código anterior usando genéricos.
Ejemplo 2: clase genérica
Demostración de clase pública {
público estático vacío principal (String [] argumentos) {
System.out.println("Utilice números de punto flotante para representar coordenadas: ");
// Después de reescribir con genéricos, no es necesario realizar una transformación descendente en los datos utilizados.
Punto<Doble> p = nuevo Punto<Doble>(12.23,23.21);
System.out.println("Coordenadas X" + p.getX());
System.out.println("Coordenadas Y" + p.getY());
System.out.println();
System.out.println("Usar números enteros para representar coordenadas: ");
Punto<Entero> p2 = nuevo Punto<Entero>(12, 23);
System.out.println("Coordenadas X" + p2.getX());
System.out.println("Coordenadas Y" + p2.getY());
System.out.println();
System.out.println("Representando coordenadas como una cadena: ");
Punto<Cadena> p3 = nuevo Punto<Cadena>("29 grados de latitud norte", "113 grados de longitud este");
System.out.println("Coordenada X" + p3.getX());
System.out.println("Coordenadas Y" + p3.getY());
}
}
Si pasamos deliberadamente diferentes tipos de datos en este momento:
Punto<Doble> p = nuevo Punto<Doble>("29 grados de latitud norte",12.22);
Entonces, se informará un error durante la compilación.
Aunque los genéricos están definidos, si no utiliza el mecanismo genérico en el constructor, tratará los datos como un Objeto.
El propósito de esto es principalmente ser compatible con códigos antiguos anteriores a JDK1.4, como
Punto p = nuevo Punto(22.11,23.21);
El resultado final de la ejecución es el mismo, pero aparecerá un mensaje de advertencia durante la compilación.
Ejemplo 3: métodos genéricos
Como puede ver en el ejemplo anterior, una vez que se especifica el tipo de objeto en el constructor, se usará el mismo tipo en toda la clase.
El ejemplo más típico se utiliza en el marco de la colección, como por ejemplo: ArrayList<Integer> al = new ArrayList<Integer>();
En este momento, todos los tipos de objetos operados en al son enteros.
Sin embargo, a veces no queremos arreglar el objeto de operación, sino utilizar tecnología genérica de manera más flexible.
En este momento, puedes probar el método genérico.
público <E> espectáculo vacío (E e) {
System.out.println(e);
}
}
Demostración de clase pública {
público estático vacío principal (String [] argumentos) {
Imprimir p = nueva Imprimir();
p.imprimir(12);
p.print("hola");
p.show(nuevo entero(33));
p.mostrar(23);
}
}
De hecho, de esta manera, no hay gran diferencia con el uso de objetos Object en los métodos.
Es más, después de JDK1.5, se agregó la función de unboxing automático, eliminando la necesidad de una transformación descendente.
Ejemplo 4: interfaz genérica
//Método de implementación uno:
clase InterDemo1 implementa Inter<String> {
impresión pública vacía (cadena t) {
System.out.println("imprimir: " + t);
}
}
//Método de implementación dos:
clase InterDemo2<T> implementa Inter<T> {
impresión de vacío público (T t) {
System.out.println("imprimir: " + t);
}
}
demostración de clase {
público estático vacío principal (String [] argumentos) {
InterDemo1 id1 = nuevo InterDemo1();
id1.print("hola");
InterDemo2<Entero> id2 = nuevo InterDemo2<Entero>();
id2.print(nuevo entero(23));
}
}
Hay dos formas de implementar una interfaz genérica. Una es especificar el tipo genérico al implementarla.
La otra es seguir utilizando genéricos y determinar el tipo genérico durante la construcción.