La restituzione delle collezioni non modificabili ti riporta solo alle eccezioni di runtime?

6

Visto che non ci sono interfacce di collezioni non modificabili distinte, non ti stai solo impostando per le eccezioni di runtime restituendo le raccolte non modificabili dalle invocazioni dei metodi? Esempio:

public class Start {    
    public static void main(String[] args) {
        try {
            List<String> listA = getListA();
            listA.add("whatever");
            System.out.println("listA: " + listA.get(0));

            List<String> listB = getListB();
            listB.add("whatever");
        } catch(Exception e) {
            System.out.println("SURPRISE!!! you should have known that listB was unmodifible.");
        }
    }

    static List<String> getListA() {
        return new ArrayList();
    }

    static List<String> getListB() {
        return Collections.unmodifiableList(new ArrayList());
    }
}
  • Nel migliore dei casi, in javadoc potrei scrivere in grassetto " la Collezione restituita non è modificabile !"?
  • In quale scenario sta tornando le Unmodifiable Collections vale il rischio di eccezioni di runtime?
posta konishiki 13.03.2016 - 03:38
fonte

2 risposte

6

Returning Unmodifiable Collections only tees you up for runtime exceptions?

Sì e no.

  • Sì, lo fa.

  • No, non solo fa quello. Inoltre impedisce che si verifichi una classe di problemi; ovvero problemi in cui alcuni codici hanno effettivamente modificato una raccolta che non avrebbe dovuto.

Quindi quali sono le alternative in Java?

  • Invece di restituire un wrapper non modificabile per una raccolta, puoi restituire una copia della collezione originale. Problemi:

    1. La copia di una grande raccolta è costosa.
    2. Il chiamante potrebbe finire per modificare involontariamente la copia quando "necessita" di modificare l'originale. In altre parole, diagnosticare il problema radice (concettuale) diventa più difficile.
  • Cerca di esprimere modificabile contro non modificabile tramite classi e interfacce. Le persone hanno provato ... ma non funziona.

In breve, l'approccio Java delle collezioni non modificabili che generano un'eccezione quando si tenta di modificarle è probabilmente la migliore soluzione possibile nel contesto dell'attuale sistema di tipi Java. Le eccezioni sono in realtà una buona cosa ... perché rendono più facile diagnosticare i problemi sottostanti.

At best, in javadoc I could write in bold letters "the returned Collection is Unmodifiable!"?

Sì. Questo è consigliabile. Anche se le lettere in grassetto sono probabilmente sconsigliabili. (Troppe urla rendono le persone sorde ...)

In what scenario is returning Unmodifiable Collections worth the risk of runtime exceptions?

Vorrei considerarlo farlo ogni volta che il comportamento corretto dell'API dipende dal fatto che il chiamante non modifichi la raccolta restituita. (È inoltre necessario valutare l'impatto sulle prestazioni, ad esempio il costo di creazione degli oggetti wrapper e il costo aggiuntivo per le chiamate al metodo avvolto.)

    
risposta data 13.03.2016 - 04:27
fonte
6

Non so perché la gente pensa a tali eccezioni come rischiose. Lo sviluppatore scrive il codice utilizzando add . Lo sviluppatore pensa che potrebbe essere una buona idea testare il codice che ha appena scritto. Lo sviluppatore ottiene una grande eccezione spaventosa. Lo sviluppatore corregge il codice.

Molto più rischioso è restituire un riferimento mutabile a una struttura di dati che è ancora utilizzata internamente a una classe, forse per evitare una costosa copia difensiva. Quindi quella struttura di dati è modificata esternamente in un modo che la classe originale non prevedeva, causando un bug sottile che non è catturato dal test, perché non è direttamente correlato al codice che era solo cambiato.

Naturalmente, questo è lontano dal modo ideale per gestire le collezioni immutabili. Le implementazioni decenti hanno funzioni add che restituiscono una nuova raccolta che condivide il più possibile la vecchia raccolta senza mutarla. Tuttavia, come wrapper veloce per rimuovere un certo insieme di errori, non è la cosa peggiore.

    
risposta data 13.03.2016 - 06:36
fonte

Leggi altre domande sui tag