Quando e perché dovremmo usare i puntatori immutabili?

7

In Java, l'oggetto String è sia immutabile che anche un puntatore (noto anche come tipo di riferimento). Sono sicuro che ci sono altri tipi / oggetti che sono entrambi immutabili e un puntatore e che si estende oltre il semplice Java.

Non riesco a pensare a dove sarebbe auspicabile, probabilmente a causa della mia esperienza personale ho usato solo un tipo di riferimento O tipi primitivi immutabili.

Qualcuno può darmi una situazione in cui sarebbe utile per ottenere un apprezzamento per il loro significato / valore / concetto.

    
posta Dave 15.03.2013 - 16:00
fonte

5 risposte

9

Un tipo di riferimento immutabile si comporta in modo simile a un tipo di valore .

Se String non fosse immutabile, potrebbe succedere qualcosa di simile:

String a = "abc";
String b = a;
a.ReplaceCharAt(1, "X");  // this is not possible, if the type is immutable

// b is now "aXc", which might be counter-intuitive

L'immutabilità impedisce che ciò accada: ogni volta che assegno una stringa a una variabile, posso essere sicuro che questa stringa non cambierà fino a quando non riasseggerò la variabile.

D'altro canto, otteniamo ancora i vantaggi dei tipi di riferimento per String :

  • Nell'esempio sopra, abc verrebbe memorizzato solo una volta in memoria.
  • Le stringhe possono essere di dimensioni variabili.

Quest'ultimo è probabilmente il motivo principale per cui le stringhe sono tipi di riferimento in Java e .NET. Spesso , tipi di valore sono memorizzati in pila. Per mettere qualcosa in pila, il compilatore deve conoscere la sua dimensione in anticipo, il che è un po 'difficile per stringhe di dimensioni diverse.

    
risposta data 15.03.2013 - 16:08
fonte
36

In primo luogo consideriamo perché è utile avere stringhe che sono immutabili. Considera lo schizzo seguente:

void Safe(string s)
{
    if (!SecurityCheck(s)) { throw new SecurityException(); }
    Dangerous(s);
}

Metodo Safe controlla se la stringa s è "sicura". Forse con "sicuro" intendiamo "l'utente è autorizzato ad accedere a questa tabella di database", o "la stringa non contiene HTML che potrebbe essere usato in un attacco di cross-site scripting", o qualsiasi altra cosa. Solo se la stringa è sicura, passa a un metodo che fa qualcosa di pericoloso con esso.

Se le stringhe fossero modificabili, un utente malintenzionato potrebbe passare una stringa "sicura" e quindi dopo il controllo di sicurezza , muta la stringa in una stringa "pericolosa". Ottenere i tempi giusti potrebbe essere complicato, ma ovviamente gli aggressori possono provare più volte, e devono solo riuscire una volta.

Questo illustra il primo valore di dati immutabili: fatti dedotti in passato sui dati rimangono veri in futuro . Se hai una coda immutabile e chiedi quanti elementi ci sono in essa, la risposta che hai ottenuto cinquemila nanosecondi fa è ancora corretta . Ciò ti consente di effettuare calcoli con sicurezza.

Il secondo grande valore dei dati immutabili è che abilita persistenza . Per persistenza non intendo la capacità di serializzare su disco (anche se ciò è utile), ma piuttosto la possibilità di riutilizzare una porzione di una struttura dati quando si costruisce una struttura dati più grande . Se hai un grande albero immutabile e vorresti che fosse un sotto-albero di un albero più grande, nessun problema. Sai che non cambierà, quindi puoi condividere i dati in sicurezza. Ma se hai, per esempio, una coda mutabile e vorresti usare il suo contenuto in un'altra struttura dati, dovrai fare una copia.

Questo è solo un breve schizzo; guarda la mia serie di articoli su strutture dati immutabili per maggiori dettagli:

link

    
risposta data 17.03.2013 - 16:38
fonte
5

Ahh ... la stringa benedetta, è il fotone del mondo del software. A seconda di come lo guardi, mostra proprietà di un tipo di riferimento o di un tipo di valore.

Il vantaggio di essere un tipo di riferimento è che puoi passarlo per riferimento. Ma se ho dichiarato una stringa come "MyConstantValueString" e l'ho passata a una funzione, non vorrei che quella funzione cambi il valore perché mi aspetto sempre che sia "MyConstantValueString".

Rendendolo immutabile, ottieni i vantaggi del passaggio per riferimento (nessuna copia necessaria) con la sicurezza di sapere che la stringa che stai indicando non cambierà mai a meno che tu non la punti esplicitamente a un'altra.

Ci sono altri scenari in cui questo sarà utile. Pensa ad esempio a una coda funzionale. Per riferimento, ti rimando al eccellente lavoro di Eric Lippert (è in C # ma è abbastanza facile da tradurre in Java, e consiglio di leggere l'intera serie, è un'apertura piuttosto accattivante). Dove dovrei voler usare una coda funzionale e che uso sarebbe?

Che ci crediate o no, le code funzionali sono utili per ... fare la fila. Per esempio. Ho un lavoro che deve essere fatto, ho bisogno di consentire ai clienti di aggiungere lavoro da fare, consentendo anche ai lavoratori di tirare fuori il lavoro e farlo. Internamente, la coda è immutabile con un solo scrittore e lettore interno. Esternamente, posso evitare la sincronizzazione semplicemente dicendo allo scrittore di aggiungere il mio lavoro alla coda e andare avanti. Nel frattempo il lettore può estrarre una serie di articoli e distribuirli ai lavoratori anche in modo asincrono. Ciò riduce tremendamente i colli di bottiglia. In realtà, questo è il modo in cui ZeroMQ è strutturato .

    
risposta data 15.03.2013 - 16:20
fonte
1

Una stringa è un puntatore che punta a un oggetto immutabile. Il puntatore stesso non è immutabile. Le modifiche alle stringhe vengono apportate cambiando il puntatore in modo che punti a un nuovo oggetto immutabile.

Le stringhe sono immutabili precisamente in modo che una variabile che è in realtà un puntatore può essere trattata come una variabile normale, piuttosto che un puntatore.

Poiché le stringhe sono immutabili, un oggetto stringa (ad esempio un puntatore) può essere passato in giro, senza preoccuparsi di cambiare la cosa a cui punta. Questo è il vantaggio del sistema.

    
risposta data 15.03.2013 - 16:08
fonte
0

La tua domanda mi dice che dovresti davvero leggere Efficace Java di Joshua Bloch. La prima edizione è disponibile online come PDF gratuitamente, ad esempio qui come PDF (nota: in particolare il capitolo Singleton è obsoleto, e mancano altri elementi più recenti, quindi considera di ottenere la 2a edizione se ti piace il libro). Tutti i programmatori Java, anche quelli esperti, che non l'hanno ancora fatto, dovrebbero esaminare gli elementi del libro almeno a colpo d'occhio e studiare attentamente tutto ciò che non conoscono già.

Nel 1 ° ed. L'articolo 13 nel capitolo 4 è intitolato "Favor Immutability" e analizza l'argomento più a lungo di quanto sia ragionevole in una risposta. Ma in breve, dovresti chiedere, perché ci sono tipi di riferimento che non sono immutabili. Breve elenco dei vantaggi dell'immutabilità: semplice in più modi, intrinsecamente thread-safe.

L'unico svantaggio di oggetti immutabili è: se vuoi cambiare qualche proprietà dell'oggetto immutabile, devi creare un nuovo oggetto, come lo snippet String s=""; s=s+5; : prima ha un'istanza di stringa vuota, quindi crea una nuova istanza di stringa con valore %codice%). Inoltre, i singleton che hanno cambiato lo stato non possono essere immutabili, per ovvi motivi.

    
risposta data 17.03.2013 - 18:44
fonte

Leggi altre domande sui tag