2011-11-21 10 views
20

Encontré la siguiente pregunta Is Java "pass-by-reference" or "pass-by-value"?.¿Puedo cambiar el valor del objeto String pasado a mi método?

He leído casi toda ella, pero no pudo encontrar a cabo con todo lo que debería hacer si quiero el método foo(-), para cambiar mis String 's valor? (tal vez o no también, no me importa).

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

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

Quiero ver bla bla en la consola. ¿Es posible?

Respuesta

29

No se puede cambiar el valor de errorText en foo ya que el método está actualmente declarado. Aunque está pasando una referencia de String errorText en foo, Java String s son inmutables; no puede cambiarlos.

Sin embargo, puede usar StringBuffer (o StringBuilder). Estas clases se pueden editar en su método 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); 
    } 
} 

Otras soluciones son utilizar una clase contenedora (crear una clase que contenga la cadena de referencia, y cambiar la referencia en foo), o simplemente devuelve la cadena.

1

Los valores de cadena son inmutables, por lo que una vez que obtienes un valor, te quedas atrapado.

0

Literal String s son tratadas especialmente por el lenguaje Java; su código es más o menos 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); 
} 

En otras palabras, estas a señalar la referencia local errorText a una String objeto diferente, que afecta a nada fuera del método.

En términos más generales, sin embargo, String s son inmutables; no hay forma de modificarlos.

0

Puede reasignar la referencia de la secuencia:

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

error = foo(error); 
4

O bien utilizar el valor de retorno del método o crear una clase contenedora.

tenerlo devolver el valor:

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

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

Wrap el valor de un objeto:

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

gracias, buena solución – merveotesi

3

Sí se puede cambiar esto con ayuda de reflexiones, pero su contra el 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); 
} 
Cuestiones relacionadas