Sto studiando i generici in questo periodo e oggi ho trovato questo mistero per me.In che modo la cancellazione di Java influisce sugli array generici?
Consideriamo la seguente classe dummy:
public class Main{
public static void main(String[] args) {
Container<Integer> c = new Container<Integer>();
c.getArray(); //No Exception
//c.getArray().getClass(); //Exception
//int a = c.getArray().length; //Exception
}
}
class Container<T> {
T[] array;
@SuppressWarnings("unchecked")
Container() {
array = (T[])new Object[1];
}
void put(T item) {
array[0] = item;
}
T get() { return array[0]; }
T[] getArray() { return array; }
}
causa di cancellazione, in fase di esecuzione, il [] tipo di ritorno T del metodo GetArray() viene trasformato in un oggetto [], che è completamente ragionevole me.
Se si accede a tale metodo così com'è (c.getArray()) non vengono generate eccezioni, ma se proviamo a chiamare alcuni metodi sull'array restituito, ad esempio c.Array(). GetClass() o . se si cerca di accedere ad un campo, per esempio c.getArray() lunghezza, quindi la seguente eccezione viene generata:
eccezione in filetto java.lang.ClassCastException "main": [Ljava.lang. Oggetto; non può essere lanciato su [Ljava.lang.Integer;
Perché viene generata questa eccezione? Perché non viene generato anche per la semplice chiamata c.getArray()? Perché sta provando a trasmettere a Integer [] se stiamo semplicemente chiamando getClass() o accedendo alla lunghezza? Sono getClass() e lunghezza non disponibili anche per Object []?
Grazie in anticipo per le vostre molte (spero) ed esplicativo (spero anche questo) risposte.
Per dereferenziare il valore di 'c.getArray()', un riferimento ad esso deve essere temporaneamente memorizzato nello stack. Posso immaginare che JLS dica - da qualche parte, ancora guardando - che questa variabile temporanea debba essere controllata per vedere se è il tipo non cancellato (dato che si conosce il tipo non registrato lì). –
Infatti, funziona se si esegue il dereferenziamento in un metodo come 'static void foo (Container c) {c.getArray(). GetClass(); } ' –
C'è una differenza interessante nel bytecode se si cambia' 'in'