2009-08-08 18 views
44

Qualcuno potrebbe dirmi qual è il significato della seguente riga in un contesto di Java:finale manipolazione variabile in Java

variabile finale può ancora essere manipolato meno che non sia immutabile

Per quanto come so, dichiarando qualsiasi variabile come definitiva, non è possibile cambiarla nuovamente, quindi cosa significano con la parola immutabile nella riga sopra?

risposta

95

che significa che se la variabile finale è un tipo di riferimento (cioè non un primitivo come int), allora è solo il riferimento che non può essere modificato. Non è possibile fare riferimento a un oggetto diverso, ma i campi dell'oggetto a cui si riferisce possono ancora essere modificati, se la classe lo consente. Per esempio:

final StringBuffer s = new StringBuffer(); 

Il contenuto del StringBuffer può ancora essere modificato arbitrariamente:

s.append("something"); 

Ma non si può dire:

s = null; 

o

s = anotherBuffer; 

Sul altra mano:

final String s = ""; 

stringhe sono immutabili - semplicemente non c'è alcun metodo che permetta di modificare una stringa (a meno che non si utilizza Reflection - e andare all'inferno).

+0

La stessa cosa vale per la raccolta troppo giusta? – pramodc84

+0

@ pramodc84: è lo stesso per tutte le variabili. La maggior parte delle collezioni sono comunque modificabili. –

+0

Quindi, come posso cambiarlo con la riflessione? =) –

16

Se si dispone di un riferimento finale per un oggetto Java è ancora possibile manipolarlo, ma non è possibile modificare il suo riferimento. Per esempio questo codice è perfettamente legale:

import javax.swing.JLabel; 

class Test1 { 
    private final static JLabel l = new JLabel("Old text"); 
    public static void main(String[] args) { 
     System.err.println(l.getText()); 
     l.setText("New Text"); 
     System.err.println(l.getText()); 
    } 
} 

Ma non si può dire:

l = new JLabel("Newest Text"); 

Dopo la prima assegnazione a l. Si noti che si può fare questo, però:

import javax.swing.JLabel; 

class Test1 { 
    public static void main(String[] args) { 
     final JLabel l; 
     String s = getArbitaryString(); // Assume this method returns a string 
     l = new JLabel(s); 
     System.err.println(l.getText()); 
    } 
} 

questo può essere fatto perché quando l viene dichiarato che non è assegnato a nulla nemmeno nulla. Quindi ti è permesso assegnargli qualcosa una sola volta.

La stessa cosa vale per i primitivi. È possibile assegnare un valore a questo modo:

class Test1 { 
    public static void main(String[] args) { 
     final int i; 
     i = 2; 
    } 
} 

Ma ora non si può manipolare ulteriormente dal momento che l'unica cosa che puoi fare per tipi primitivi è quello di assegnare i valori a loro.

-2

È ancora possibile modificare una variabile "finale" utilizzando Reflection.

+1

Si può ma non è quello che intendeva. –

+0

In realtà, non puoi. Otterrai una java.lang.IllegalAccessException. –

+0

In realtà, è possibile. Provalo. – Javamann

3

Come altri hanno già detto, significa che è possibile manipolare l'oggetto i punti variabili a, ma non è possibile modificare il riferimento (cioè assegnare un altro oggetto alla variabile).

oggetti che sono mutevoli in base alla progettazione, come ad esempio un List possono essere cambiati (è possibile aggiungere gli elementi a loro), mentre se si dispone di un oggetto immutabile, come ad esempio un String o Integer non sarà in grado di cambiarlo (tutto le operazioni che la classe String supporta restituiscono una nuova istanza e non modificano l'oggetto reale).

4

Non è possibile modificare a quale oggetto o valore si riferisce una variabile finale. È possibile assegnare una variabile finale solo una volta.

Questo non ha alcun effetto sulla possibilità di modificare lo stato dell'oggetto. L'oggetto stesso può ancora essere manipolato a meno che non sia codificato in modo tale che questa manipolazione sia proibita. Un oggetto immutabile è un oggetto il cui stato non può cambiare.

0

È possibile chiamare qualsiasi metodo su di esso anche se il metodo può modificare lo stato dell'oggetto a cui punta il riferimento. Per esempio

final MyClass myClass = new MyClass(); 
myClass.setVar(something); 

Questo va bene perché myClass sé non sta cambiando, cioè non si sta facendo myClass = myClass1;.

0

Quello che mi uccide sempre?

Se si desidera che le variabili finali siano effettivamente al sicuro come si pensava, è necessario molto codice aggiuntivo per restituire una copia di una stringa [].

0

È possibile manipolare variabili finali mutabili per es. di tipo StringBuffer ma non puoi manipolare le variabili finali dei tipi immutabili.

In caso di variabili mutabili, il nuovo oggetto non viene creato ogni volta che viene modificato il valore. Ma in caso di tipi immutabili, ogni volta che si modifica il valore, viene creato un nuovo oggetto, quindi quando lo si rende definitivo, non è possibile modificarlo.

0

Sì, la variabile finale può essere modificata.

final StringBuffer s = new StringBuffer(); 
    // won't work 
    s = new StringBuffer(); 
    //this works 
    s.append("hai"); 

Non è possibile modificare il riferimento, ma i campi del l'oggetto può essere modificato. for more details

Problemi correlati