¿Qué son los Java generics?: aprende a usarlos

Contenido del Bootcamp Dirigido por: | Última modificación: 19 de septiembre de 2024 | Tiempo de Lectura: 4 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

Los Java generics, también llamados en español genéricos en Java, son una característica que se introdujo en JDK 5.0 y tuvo desde el principio el objetivo de mejorar la seguridad del código, reducir errores y de hacer aplicaciones más robustas. Grosso modo, los Java generics nos permiten escribir clases, interfaces y métodos que tengan la posibilidad de operar con cualquier tipo de dato, lo que proporciona una capa de abstracción sobre los tipos.

El día de hoy queremos mostrarte qué son exactamente los Java generics, cómo funcionan y por qué deberías usarlos en el momento de aprender Java.

¿Por qué usar Java generics?

Previo a la llegada de los Java generics, existía un problema bastante común y era el del riesgo de errores de tipo en tiempos de ejecución. Si por ejemplo tenías una lista de objetos en donde se mezclaban distintos tipos de datos, esto podía generar errores inesperados al intentar acceder a ellos.

Con los generics en Java es posible definir un tipo específico que puede ser usado en una clase o método. Este proceso nos ayuda a mejorar la seguridad de nuestro código y también elimina la necesidad de hacer conversiones explícitas de tipo (llamadas casting).

Ventajas de los Java Generics
Ventajas de los Java Generics

¿Cómo funcionan los Java generics?

Los Java generics funcionan por medio de clases, interfaces y métodos genéricos. Esto quiere decir que es posible crear o definir una clase, método o interfaz que opere con cualquier tipo de dato, pero sin necesidad de especificar el tipo concreto en el momento de la definición.

Definición de clases genéricas

Las clases genéricas pueden definirse haciendo uso de un parámetro de tipo dentro de ángulos (<>). Dicho parámetro actúa como marcador de posición para un tipo que se especificará cuando se haya instanciado la clase. Veamos:

public class Caja<T> {
private T contenido;

public void setContenido(T contenido) {
this.contenido = contenido;
}

public T getContenido() {
return contenido;
}
}

Para este ejemplo, T es un tipo genérico que será reemplazado por un tipo real, ya sea String, Integer o cualquier otro, al momento en el que se instancie la clase Caja. De este modo, puedes tener una caja que solo acepte números, o bien, una que solo acepte cadenas de texto.

public class Main {
public static void main(String[] args) {
Caja<String> cajaDeTextos = new Caja<>();
cajaDeTextos.setContenido("Hola, Generics!");
System.out.println(cajaDeTextos.getContenido());

Caja<Integer> cajaDeNumeros = new Caja<>();
cajaDeNumeros.setContenido(123);
System.out.println(cajaDeNumeros.getContenido());
}
}

Para este caso, en el momento en que instancias la clase Caja, vas a definir qué tipo de dato va a almacenar (String o Integer), y así Java se encarga del trabajo duro y asegurar que solo ese tipo de dato sea almacenado en la caja.

Métodos genéricos

Del mismo modo que las clases, los objetos en Java también pueden ser genéricos. Es decir, puedes crear métodos que funcionen con cualquier tipo de dato. Veamos un ejemplo para entender mejor esto:

public <T> List<T> convertirArrayALista(T[] array) {
return Arrays.asList(array);
}

En este método tenemos varias partes:

  1. Declaración del tipo genérico <T>:
    • La parte importante del método genérico es la declaración <T> justo antes del tipo de retorno List<T>. Esta declaración le indica al compilador que el método utilizará un tipo genérico T, que puede ser cualquier tipo de objeto (como Integer, String, Double, etc.).
    • T es un nombre de marcador que representa el tipo genérico y puedes usar cualquier otra letra o palabra pero, por convención, se usa T (de «Type»).
  2. Parámetro del método:
    • El método recibe como parámetro un array de tipo genérico (T[] array), lo que significa que puede aceptar un array de cualquier tipo, siempre que ese tipo esté determinado en la llamada al método. Por ejemplo, podría ser un array de String[], Integer[], etc.
  3. Tipo de retorno:
    • El método devuelve una lista del mismo tipo genérico (List<T>), es decir, la lista que se devolverá contendrá elementos del mismo tipo que el array que recibió como parámetro.
  4. Conversión del array a una lista:
    • En el cuerpo del método se utiliza Arrays.asList(array), que es un método estándar de Java que convierte un array en una lista. Como el array es del tipo T[], la lista resultante será del tipo List<T>, esto nos hace asegurarnos que tanto el array como la lista contengan el mismo tipo de elementos.

Java generics con límites

Vas a encontrar que en ocasiones es necesario restringir los tipos de datos que se pueden usar en un tipo genérico. Para esto se usan los límites. Un tipo genérico puede restringirse a a que se extienda a una clase específica o simplemente una interfaz:

public <T extends Number> void imprimirNumeros(T[] numeros) {
for (T numero : numeros) {
System.out.println(numero);
}
}

Este método genérico solo funcionará con clases que extiendan Number, como Integer, Double, o Float.

Si te interesó el tema de los Java Generics y quieres seguir aprendiendo sobre el ecosistema Java, tenemos un bootcamp que te sacará de tu zona de confort al enseñarte cosas únicas. Se trata de nuestro curso java, en donde, en poco tiempo, aprenderás miles de cosas que no imaginaste sobre el lenguaje de programación más popular en todo el mundo. Entenderás por qué su fama no es gratuita, al comprender todas sus herramientas y la cantidad de posibilidades que tienes gracias a este lenguaje. Te ayudaremos a formar tu carrera y entrar en la mejor industria tecnológica. ¡Únete a nosotros ahora!

Posts más leídos

¡CONVOCATORIA ABIERTA!

Java y Spring Boot

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado