Perché non ImmutableList
estendere List
?
ImmutableCollection
non estende java.util.Collection
(e ImmutableList
non si estende java.util.List
) perché Collection
ha mutando metodi come add()
e remove()
. Se le collezioni immutabili avessero questi metodi, avrebbero sempre dovuto lanciare UnsupportedOperationException
. Per gli utenti di collezioni immutabili, sarebbe strano vedere add()
e remove()
nelle scelte di completamento automatico come metodi chiamabili.
Perché Javadoc impone un contratto che tutte le implementazioni ImmutableList
implementino anche List
?
Si tratta di uguaglianza. Un ImmutableList
deve essere uguale a List
, assumendo che entrambi gli elenchi abbiano gli stessi contenuti nello stesso ordine. List.equals()
imposes a Javadoc contract che afferma:
restituisce true se e solo se l'oggetto specificato è anche una lista, entrambi liste hanno le stesse dimensioni, e tutte le corrispondenti coppie di elementi a le due liste sono uguali.
Che cosa significa che "l'oggetto specificato è anche un elenco?" Possiamo vedere in AbstractList.equals()
che significa instanceof List
.
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
...
}
Così tutti ImmutableList
implementazioni devono anche implementare List
per equals()
a lavorare in modo simmetrico. Le fabbriche di raccolta immutabili nascondono già dettagli di implementazione come il fatto che una lista immutabile con un singolo elemento è implementata da un ImmutableSingletonList
. Si conclude anche nascondendo l'interfaccia List
.
Interop
Un vantaggio di questo progetto è che ImmutableList
può essere gettato a List
che è importante per l'interoperabilità con le API esistenti.
// Library method - cannot refactor the parameter type
public void printAll(List<?> list)
{
for (Object each : list)
{
System.out.println(each);
}
}
ImmutableList<Integer> immutableList = Lists.immutable.with(1, 2, 3);
List<Integer> castList = immutableList.castToList();
printAll(castList);
// also works
printAll((List<?>) immutableList);
// throws UnsupportedOperationException
castList.add(4);
Nota: Sono uno sviluppatore su GS Collections.
fonte
2015-04-08 14:34:51
Cosa * fa * si estende? –
Alla radice, estende 'java.lang.Iterable' – Wins
Design strano. Invece di inserire un requisito inapplicabile in Javadoc, avrebbero potuto semplicemente scrivere 'extends java.util.Elenco e farlo applicare automaticamente. – EJP