Sobes.tech
Middle

Quali sono le possibilità in Generics?

sobes.tech AI

Risposta dell'AI

I generici consentono di creare classi, interfacce e metodi parametrizzati.

Funzionalità principali:

  • Riutilizzo del codice: Creazione di strutture dati e algoritmi universali che funzionano con qualsiasi tipo.
  • Sicurezza dei tipi durante la compilazione: Gli errori di tipo vengono rilevati in fase di compilazione, non durante l'esecuzione. Elimina la necessità di cast manuali e potenziali errori ClassCastException.
  • Migliore leggibilità: Il codice diventa più comprensibile poiché indica chiaramente con quali tipi lavora.

Esempi:

  • La classe contenitore List<T> può contenere elementi di qualsiasi tipo T.
  • Il metodo static <T> T getFirst(List<T> list) può restituire il primo elemento di una lista di qualsiasi tipo.

Limitazioni dei Generici:

  • Non è possibile creare istanze di tipi generici: new T().
  • Non si possono usare tipi primitivi come parametri di tipo (ad esempio, List<int> - errato, bisogna usare List<Integer>).
  • Non si possono creare array di tipi generici direttamente (ad esempio, T[] array = new T[10] - errato, bisogna usare ArrayList o castare).
  • Non si possono usare campi statici di tipi generici direttamente.
  • Le informazioni sui tipi vengono cancellate in fase di esecuzione (Type Erasure), tranne i wildcards limitati.

Wildcards e Parametri di Tipo Limitati:

  • <?>: Tipo sconosciuto. Permette di leggere elementi, ma non di scrivere.
  • <? extends T>: Limite superiore. Permette di lavorare con tipi che sono sottotipi di T. È possibile leggere elementi di tipo T o dei suoi supertipi, ma non scrivere (tranne null).
  • <? super T>: Limite inferiore. Permette di lavorare con tipi che sono supertipi di T. È possibile scrivere elementi di tipo T o dei suoi sottotipi, ma leggendo si ottiene solo Object.

Esempio:

// Metodo che può stampare elementi di qualsiasi lista,
// che contiene sottotipi di Number
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Errore di compilazione
}

// Metodo che può aggiungere Integer a una lista,
// che contiene Integer o i suoi supertipi
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Errore di compilazione, ritorna Object
}