Sobes.tech
Middle

¿Cuáles son las posibilidades en Generics?

sobes.tech AI

Respuesta de la IA

Los genéricos permiten crear clases, interfaces y métodos parametrizados.

Funciones principales:

  • Reutilización de código: Creación de estructuras de datos y algoritmos universales que funcionan con cualquier tipo.
  • Seguridad de tipos en tiempo de compilación: Los errores de tipo se detectan en la fase de compilación, no en tiempo de ejecución. Elimina la necesidad de hacer conversiones de tipos manuales y errores potenciales relacionados ClassCastException.
  • Mejor legibilidad: El código se vuelve más comprensible, ya que indica claramente con qué tipos trabaja.

Ejemplos:

  • La clase contenedor List<T> puede almacenar elementos de cualquier tipo T.
  • El método static <T> T getFirst(List<T> list) puede devolver el primer elemento de una lista de cualquier tipo.

Restricciones de los genéricos:

  • No se pueden crear instancias de tipos genéricos: new T().
  • No se pueden usar tipos primitivos como parámetros de tipo (por ejemplo, List<int> - incorrecto, se debe usar List<Integer>).
  • No se pueden crear arreglos de tipos genéricos directamente (por ejemplo, T[] array = new T[10] - incorrecto, se debe usar ArrayList o hacer un casting).
  • No se pueden usar campos estáticos de tipos genéricos directamente.
  • La información de tipos se borra en tiempo de ejecución (Type Erasure), excepto los comodines limitados.

Wildcards y parámetros de tipo limitados:

  • <?>: Tipo desconocido. Permite leer elementos, pero no escribir.
  • <? extends T>: Restricción superior. Permite trabajar con tipos que son subtipos de T. Se pueden leer elementos de tipo T o sus supertipos, pero no escribir (excepto null).
  • <? super T>: Restricción inferior. Permite trabajar con tipos que son supertipos de T. Se pueden escribir elementos de tipo T o sus subtipos, pero al leer solo se obtiene Object.

Ejemplo:

// Método que puede imprimir elementos de cualquier lista,
// que contiene subtipos de Number
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Error de compilación
}

// Método que puede agregar Integer a una lista,
// que contiene Integer o sus supertipos
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Error de compilación, devuelve Object
}