2012-05-07 12 views
5

elenco non modificabile in Java può essere creato come:Qual è il tipo di elenco non modificabile in java

List<String> unModifiableStringList = Collections.unmodifiableList(myActualModifiableList); 

Questo va bene, ma qual è il tipo di runtime effettivo della lista restituita dalla funzione di cui sopra? Come possiamo accedere a quella classe? È possibile?

UPDATE: In realtà ho bisogno di sapere al momento della compilazione che un elenco non modificabile viene modificata, Dal momento che ho a che fare con un sacco di liste, alcune delle quali sono modificabili e gli altri non lo sono. Quindi è molto ingombrante da tenere traccia?

risposta

8

In realtà ho bisogno di sapere in fase di compilazione che un elenco non modificabile viene modificato.

Questo non è possibile.

O almeno, non è possibile senza creare una gerarchia di interfaccia/classe di collezioni completamente diversa. E questa è una cattiva idea, perché niente di progettato per usare collezioni regolari funzionerebbe con esso.

suppongo che sarebbe stato possibile scrivere un analizzatore di codice statico che potrebbe rilevare questo genere di cose ... in alcuni casi ... ma questo non è strettamente "fase di compilazione". Inoltre, non sono a conoscenza di alcun analizzatore di codice statico esistente che faccia questo "out of the box".


Mi chiedo se ci fosse una ragione perché l'hanno fatto in questo modo.

Ebbene nessuno dei modi si potrebbe fare questo funziona davvero.

Alternativa # 1:

public interface UnmodifiableList<T> { 
    public T get(int pos); 
    .... 
} 

public interface List<T> extends UnmodifiableList<T> { 
    public void add(T elem); 
    .... 
} 

Mentre tipizzazione statica ci può impedire di utilizzare un elenco non modificabile in cui è richiesto uno modificabili, il contrario non è vero. Ogni lista è anche una lista non modificabile ... e questo non ha molto senso.

Alternativa 2:

public interface List <T> { 
    public T get(int pos); 
    public void add(T elem); 
    .... 
} 

public interface UnmodifiableList<T> { 
    // A marker interface 
} 

tipizzazione statica Ora ci può impedire di utilizzare un elenco modificabile in cui è richiesta una umodifiable, ma non il contrario. (Ciò soddisfa le tue esigenze ...) Inoltre, una classe che implementa UnmodifiableList eredita comunque l'operazione add e non c'è nulla che impedisca a un'applicazione di provare a chiamarla.

In breve, i sistemi di tipo statico non sono in grado di gestire adeguatamente questo tipo di restrizione.

+0

Mi chiedo se ci fosse un motivo per cui l'abbiano fatto in questo modo. :( –

+2

Come regola generale, è necessario codificare le interfacce anziché le classi di runtime effettive. "Collections.unmodifiableList' è progettato, in effetti, per forzare l'utente a codificare nell'interfaccia. –

+0

@LouisWasserman - Non penso che sia rilevante alle domande di follow-up dell'OP, cioè quelle che sto rispondendo –

3

Hai provato unModifiableStringList.getClass().getName()?

A me dà

java.util.Collections$UnmodifiableRandomAccessList 

che, come si è visto dal codice sorgente, è un pacchetto di accesso classe interna statica di Collections.

+0

+1 da me ..... –

0

debug indica che il tipo di esecuzione è Collections.UnmodifiableRandomAccessList, quindi è classe interna. L'analisi del codice mostra anche che potrebbe essere Collections.UnmodifiableList.

Non dovresti provare ad accedere a questa classe, è inteso essere immutabile. Prova ad usare l'interfaccia comune, in questo caso = Collection.

3

È

static class UnmodifiableList<E> extends UnmodifiableCollection<E> 
         implements List<E> 

static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E> 
             implements RandomAccess 

static class UnmodifiableCollection<E> implements Collection<E>, Serializable 

Si tratta di classe interna di Collections, dal momento che Collections è non creare istanze ed è classe interna con visibilità pacchetto, non può accedere alla classe, ed è l'occultamento dell'implementazione in OOP.

+0

Come posso verificare nel mio codice se una lista non è modificabile o no? –

+0

@djaqeel Penso che tu possa solo controllare in fase di esecuzione, ma non compilare il tempo. E non è consigliabile controllare anche in fase di esecuzione. –