2011-11-21 14 views
20

Ho trovato la seguente domanda Is Java "pass-by-reference" or "pass-by-value"?.Posso cambiare il valore dell'oggetto String passato al mio metodo?

ho letto quasi tutto, ma non poteva sapere ancora cosa devo fare se voglio il metodo foo(-), per cambiare l' valore miei String? (forse o non fa riferimento anche a me, non ha importanza per me).

void foo(String errorText){ 
    errorText="bla bla"; 
} 

int main(){ 
    String error="initial"; 
    foo(error); 
    System.out.println(error); 
} 

voglio vedere bla bla sulla console. È possibile?

risposta

29

Non è possibile modificare il valore di errorText in foo come il metodo è attualmente dichiarato. Anche se si sta passando un riferimento della stringaa foo, Java String s è immutabile - non è possibile modificarli.

Tuttavia, è possibile utilizzare uno StringBuffer (o StringBuilder). Queste classi possono essere modificate nel metodo foo.

public class Test { 
    public static void foo(StringBuilder errorText){ 
     errorText.delete(0, errorText.length()); 
     errorText.append("bla bla"); 
    } 

    public static void main(String[] args) { 
     StringBuilder error=new StringBuilder("initial"); 
     foo(error); 
     System.out.println(error); 
    } 
} 

Altre soluzioni sono di utilizzare una classe wrapper (creare una classe per tenere il vostro riferimento String, e modificare il riferimento in foo), o semplicemente restituisce la stringa.

1

I valori di stringa sono immutabili, quindi una volta ottenuto un valore, lo si è bloccato.

0

letterale String s sono trattati appositamente dal linguaggio Java; il codice è più o meno equivalente a:

void foo(String errorText){ // at this point, errorText refers to the original string 
    errorText=new String("bla bla"); // now it refers to a new string 
} 

int main(){ 
    String error=new String("initial"); // error is a reference to the original string 
    foo(error); // pass a *copy* of the reference 
    System.out.println(error); 
} 

In altre parole, si sta solo puntando il riferimento locale errorText ad un diverso String oggetto, che colpisce nulla al di fuori del metodo.

Più in generale, tuttavia, String s sono immutabili; non c'è modo di modificarli.

0

È possibile riassegnare il riferimento String:

String foo(String err) { 
    return "bla blah" 
} 

error = foo(error); 
4

O utilizzare il valore di ritorno del metodo o creare una classe wrapper.

averlo restituire il valore:

String foo(String errorText){ 
    return "bla bla"; 
} 

int main(){ 
    String error="initial"; 
    error = foo(error); 
    System.out.println(error); 
} 

Avvolgere il valore in un oggetto:

class StringWrapper { 
    private String string; 
    public StringWrapper(String s) { 
     this.string = s; 
    } 
    public String getString() { 
     return this.string; 
    } 
    public void setString(String s) { 
     this.string = s; 
    } 
} 

void foo(StringWrapper errorText){ 
    errorText.setString("bla bla"); 
} 

int main(){ 
    StringWrapper error=new StringWrapper("initial"); 
    foo(error); 
    System.out.println(error.getString()); 
} 
+0

grazie, bella soluzione – merveotesi

3

Sì, è possibile modificare questo con l'aiuto di riflessioni, ma la sua contro il dominio.

void foo(String errorText) { 
    try { 
     final Class<String> type = String.class; 
     final java.lang.reflect.Field valueField = type.getDeclaredField("value"); 
     valueField.setAccessible(true); 
     valueField.set(errorText, "bla bla".toCharArray()); 
    } catch (Exception e) { 
    } 

} 

public static void main(String[] args) { 
    String error = new String("initial"); 
    foo(error); 
    System.out.println(error); 
} 
Problemi correlati