Tipi grezzi in Java

1. Introduzione

In questo rapido tutorial, daremo un'occhiata ai tipi grezzi, cosa sono e perché dovremmo evitarli.

2. Tipi grezzi

Un tipo grezzo è un nome per un'interfaccia o una classe generica senza il suo argomento di tipo:

List list = new ArrayList(); // raw type

Invece di:

List listIntgrs = new ArrayList(); // parameterized type

List è un tipo di interfaccia parametrizzato List mentre List è un tipo grezzo di List di interfaccia .

I tipi non elaborati possono essere utili quando si interfaccia con codice legacy non generico.

Altrimenti, però, è scoraggiato. Questo è perché:

  1. Non sono espressivi
  2. Mancano di sicurezza dei tipi e
  3. I problemi vengono osservati in fase di esecuzione e non in fase di compilazione

3. Inespressivo

Un tipo grezzo non documenta e si spiega come fa un tipo parametrizzato.

Possiamo facilmente dedurre che un List di tipo parametrizzato è un elenco che contiene String s. Tuttavia, un tipo grezzo manca di questa chiarezza, rendendo difficile lavorare con esso e con i suoi metodi API.

Vediamo la firma del metodo get (int index) nell'interfaccia List per capirlo meglio:

/** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException if the index is out of range * (index = size()) */ E get(int index);

Il metodo get (int index) restituisce una stringa alla posizione index nel tipo parametrizzato List .

Tuttavia, per un elenco di tipo non elaborato , restituisce un oggetto . Così, siamo tenuti a prendere sforzo supplementare per ispezionare e identificare il tipo di elemento nel tipo grezzo List e aggiungere un adeguato tipo-casting. Questo può introdurre bug in fase di esecuzione poiché il tipo raw non è sicuro .

4. Non a prova di tipo

Otteniamo comportamenti pre-generici con tipi grezzi. Pertanto, un elenco di tipo non elaborato accetta Object e può contenere un elemento di qualsiasi tipo di dati . Questo può portare a problemi di sicurezza dei tipi quando mescoliamo tipi parametrizzati e non elaborati.

Vediamolo creando un codice che istanzia un List prima di passarlo a un metodo che accetta List di tipo raw e aggiunge un Integer ad esso:

public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); } public void methodB(List rawList) { // raw type! rawList.add(1); }

Il codice viene compilato (con un avviso) e l' Integer viene aggiunto all'elenco dei tipi non elaborati quando viene eseguito. L' elenco che è stato passato come argomento ora contiene una stringa e un numero intero .

Il compilatore stampa un avviso a causa dell'utilizzo di tipi non elaborati:

Note: RawTypeDemo.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.

5. Problemi in fase di esecuzione

La mancanza di sicurezza dei tipi su un tipo grezzo ha un effetto causale che può portare a eccezioni in fase di esecuzione.

Modifichiamo l'esempio precedente in modo che il metodoA ottenga l'elemento nella posizione di indice 1 della nostra lista dopo aver chiamato il metodoB :

public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); String s = parameterizedList.get(1); } public void methodB(List rawList) { rawList.add(1); }

Il codice viene compilato (con lo stesso avviso) e genera un'eccezione ClassCastException quando viene eseguito. Ciò accade quando il metodo get (int index) restituisce un numero intero , che non può essere assegnato a una variabile di tipo String :

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

6. Conclusione

I tipi grezzi sono difficili da lavorare e possono introdurre bug nel nostro codice.

Il loro utilizzo può portare a conseguenze che possono essere disastrose e, sfortunatamente, la maggior parte di questi disastri si verificano in fase di esecuzione.

Dai un'occhiata a tutti gli snippet in questo tutorial su GitHub.