English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
En este tutorial, entenderemos mediante ejemplos los genéricos en Java, cómo crear clases y métodos genéricos y sus ventajas.
En Java,GenéricoAyuda a crear clases, interfaces y métodos que puedan utilizarse con diferentes tipos de objetos (datos). Por lo tanto, nos permite reutilizar nuestro código.
Nota:Notación:GenéricoLos genéricos no se aplican a los tipos primitivos (int, float, char, etc.).
Para entender cómo usarGenéricopodemos usar las clases de la estructura de datos Java ArrayList.
La clase ArrayList es un ejemplo de clase genérica. Podemos usar ArrayList para almacenar cualquier tipo de datos. Por ejemplo
import java.util.ArrayList; class Main { public static void main(String[] args) { //Crear una lista de arrays para almacenar datos de Integer ArrayList<Integer> list1 = new ArrayList<>(); list1.add(4); list1.add(5); System.out.println("ArrayList de Integer: ") + list1); //Crear una lista de arrays para almacenar datos de String ArrayList<String> list2 = new ArrayList<>(); list2.add("Four"); list2.add("Five"); System.out.println("ArrayList de String: ") + list2); //Crear una lista de arrays para almacenar datos de tipo Double ArrayList<Double> list3 = new ArrayList<>(); list3.add(4.5); list3.add(6.5); System.out.println("ArrayList de Double: ", + list3); } }
Resultados de salida
ArrayList de Integer: [4, 5] ArrayList de String: [Four, Five] ArrayList de Double: [4.5, 6.5]
En el ejemplo anterior, usamos la misma clase ArrayList para almacenar elementos de tipo Integer, String y Double. Debido aGenericos Java, esto es posible.
En esta línea, presten atención,
ArrayList<Integer> list1 = new ArrayList<>();
Usamos Integer dentro de los corchetes <> aquí. Los corchetes <> se llamanParámetros de tipo.
El parámetro type se utiliza para especificar el tipo de objeto (datos) al que se aplica la clase genérica o el método.
Ahora que sabemos cómo funcionan los genéricos en Java, veamos cómo crear nuestras propias clases genéricas.
class Main { public static void main(String[] args) { //Inicializar la clase genérica con datos enteros GenericsClass<Integer> intObj = new GenericsClass<>(5); System.out.println("La clase genérica devuelve:", + intObj.getData()); //Inicializar la clase genérica con datos de cadena GenericsClass<String> stringObj = new GenericsClass<>("Java Programming"); System.out.println("La clase genérica devuelve:", + stringObj.getData()); } } class GenericsClass<T> { //Variable de tipo T private T data; public GenericsClass(T data) { this.data = data; } //Método que devuelve una variable de tipo T public T getData() { return this.data; } }
Resultados de salida
La clase genérica devuelve: 5 La clase genérica devuelve: Programación Java
En el ejemplo anterior, creamos una clase genérica llamada GenericsClass. Esta clase se puede usar para manejar cualquier tipo de datos.
class GenericsClass<T> {...}
Aquí, T representaParámetros de tipoDentro de la clase Main, creamos objetos de GenericsClass llamados intObj y stringObj.
Al crear intObj, el parámetro de tipo T se reemplaza por Integer. Esto significa que intObj utiliza GenericsClass para procesar datos enteros.
Al crear stringObj, el parámetro de tipo T se reemplaza por String. Esto significa que stringObj utiliza GenericsClass para procesar datos de cadena.
Al igual que con las clases genéricas, también podemos crear nuestros propios métodos genéricos en Java.
class Main { public static void main(String[] args) { //Inicializar la clase con datos de tipo Integer DemoClass demo = new DemoClass(); demo.<String>genericMethod("Programación Java"); } } class DemoClass { //Métodos genéricos public <T> void genericsMethod(T data) { System.out.println("Este es un método genérico."); System.out.println("Los datos pasados al método son "); + data); } }
Resultados de salida
Este es un método genérico. Los datos pasados al método son: Programación Java
En el ejemplo anterior, creamos un método genérico llamado genericsMethod dentro de una clase común (DemoClass).
public <T> void genericMethod(T data) {...}
Aquí, se inserta el parámetro de tipo <T> después del modificador (public) y antes del tipo de retorno (void).
Podemos llamar al método genérico colocando el tipo real <String> entre los paréntesis del nombre del método.
demo.<String>genericMethod("Programación Java");
Nota:En la mayoría de los casos, podemos omitir el parámetro de tipo al llamar al método genérico. Esto se debe a que el compilador puede usar el valor pasado al método para coincidir con el parámetro de tipo. Por ejemplo,
demo.genericsMethod("Programación Java");
Generalmente,Parámetro de tipopuede aceptar cualquier tipo de datos (excepto tipos primitivos). Pero, si solo queremos usar generics para tipos específicos (por ejemplo, aceptar datos de tipo numérico), podemos usar tipos limitados.
Usamos la palabra clave extends. Por ejemplo,
<T extends A>
Esto significa que T solo puede aceptar tipos de datos que sean subtipos de A.
class GenericsClass <T extends Number> { public void display() {}} System.out.println("This is a bounded type generics class."); } } class Main { public static void main(String[] args) { //Crear un objeto de GenericsClass GenericsClass<String> obj = new GenericsClass<>(); } }
En el ejemplo anterior, creamos unade tipo limitadode la clase genérica. Aquí, tenga en cuenta la expresión
<T extends Number>
Esto significa que T solo puede usar tipos de datos subordinados de Number (Integer, Double, etc.).
Pero, ya hemos creado un objeto de clase genérica usando String. Es por eso que al ejecutar el programa, obtenemos el siguiente error.
GenericsClass<String> obj = new GenericsClass<>(); ^ razón: el variable de inferencia T tiene límites incompatibles restricciones de igualdad: String límites inferiores: Number donde T es un tipo-variable: T extends Number declarado en la clase GenericsClass
GenéricoNos permite escribir código que es aplicable a diferentes tipos de datos. Por ejemplo,
public <T> void genericsMethod(T data) {...}
Aquí, creamos un método genérico. Este método se puede usar para realizar operaciones en datos enteros, datos de cadena, etc.
GenéricoParámetro de tipoProporcionar información sobre los tipos de datos utilizados en el código genérico.
Por lo tanto, se pueden identificar errores en tiempo de compilación, lo que es más fácil de arreglar que los errores en tiempo de ejecución. Por ejemplo,
//Sin usar genéricos NormalClass list = new NormalClass(); //Llamada al método de NormalClass list.display("String");
En el código anterior, tenemos una clase común. Llamamos al método display() de esta clase pasando datos de cadena.
Aquí, el compilador no sabe si el valor pasado como parámetro es correcto. Pero, veamos qué sucede si usamos una clase genérica.
//Uso de genéricos GenericsClass<Integer> list = new GenericsClass<>(); //Llamar al método de GenericsClass list2.display("String"); En el código anterior, tenemos una clase genérica. Aquí, el parámetro de tipo indica que esta clase está procesando datos de tipo Integer. Por lo tanto, cuando se pasan datos de cadena en los parámetros, el compilador generará un error.
La estructura de colecciones utiliza el concepto de genéricos en Java. Por ejemplo,
// Crear un ArrayList de tipo cadena ArrayList<String> list1 = new ArrayList<>(); // Crear un ArrayList de tipo entero ArrayList<Integer> list2 = new ArrayList<>();
En el ejemplo anterior, usamos la misma clase ArrayList para manejar diferentes tipos de datos.
Al igual que ArrayList, otras colecciones (LinkedList, Queue, Maps, etc.) también son genéricas en Java.