Perché i generici java non possono essere negli array?

8

Perché quando provo a creare una matrice di ArrayList: ArrayList<Integer>[] arr=new ArrayList<Integer>[40]; c'è un errore e java non lo consente?

C'è una ragione legata all'implementazione di java di generici, generici in qualsiasi lingua o qualcosa di arbitrario?

    
posta Jakob Weisblat 04.01.2013 - 03:01
fonte

2 risposte

19

Questo è uno dei principali buchi nei generici di Java, gli array sono covariante , il che significa che una serie di tipi Foo[] è una sottoclasse di Object[] e ParentOfFoo[] . Contrasta con List<Foo> che non ha questo comportamento.

Questo era importante quando Java non aveva generici (fino a Java 5) perché altrimenti, qualcosa come una generica funzione di ordinamento era semplicemente impossibile.

Tuttavia ha questo difficile problema che gli array vogliono sapere di che tipo sono in fase di runtime . Tuttavia i generici in Java si basano sulla cancellazione dei tipi. Queste due cose non si adattano affatto e questo è il nostro problema.

Quindi, in breve, in Java 1, gli array covarianti riempivano parzialmente il buco creato da una mancanza di generici. Tuttavia, quando hanno cercato di riempire correttamente questo buco, la compatibilità all'indietro ha significato che gli array erano praticamente impossibili da implementare.

In effetti, il tizio che ha creato il framework per i generici, Martin Odersky, ha parlato di questo qui durante un'intervista sul perché ha fatto Scala. (Molto affascinante se sei interessato alla storia di Scala)

    
risposta data 04.01.2013 - 05:08
fonte
3

Is there a reason related to java's implementation of generics, generics in any language, or something arbitrary?

In realtà, è in qualche modo arbitrario.

Il problema è che consente un buco nel sistema dei tipi, dal momento che ArrayList<T>[] può essere castato a Object[] e quindi puoi mettere un ArrayList<U> nella matrice, dove U != T .

I designer Java hanno deciso di bloccare questo buco il più impazientemente possibile, non permettendo affatto a new ArrayList<T>[N] .

Tuttavia, potrebbe anche essere stato bloccato non consentendo l'upcasting di array di generici (senza un avviso "non controllato").

    
risposta data 13.02.2017 - 02:25
fonte

Leggi altre domande sui tag