web-dev-qa-db-fra.com

Puis-je changer la valeur de l'objet String transmise à ma méthode?

J'ai trouvé la question suivante Est-ce que Java est "pass-by-reference" ou "pass-by-value"? .

J'ai presque tout lu, mais je ne pouvais pas encore savoir ce que je devais faire si je voulais utiliser la méthode foo(-) pour modifier ma valeur String's value? (peut-être ou pas référence aussi, ça ne me dérange pas). 

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

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

Je veux voir bla bla sur la console. C'est possible?

24
merveotesi

Vous ne pouvez pas changer la valeur de errorText dans foo car la méthode est actuellement déclarée. Même si vous transmettez une référence de la chaîne errorText à foo, les Strings Java sont immuables - vous ne pouvez pas les modifier.

Cependant, vous pouvez utiliser un StringBuffer (ou StringBuilder). Ces classes peuvent être éditées dans votre méthode 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);
    }
}

D'autres solutions consistent à utiliser une classe wrapper (créer une classe pour contenir votre référence String et modifier la référence dans foo) ou simplement renvoyer la chaîne.

34
Jack Edmonds

Utilisez la valeur de retour de la méthode ou créez une classe wrapper.

Faites-le retourner la valeur:

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

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

Envelopper la valeur dans un objet:

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());
}
7
Erick Robertson

Oui, vous pouvez changer cela à l'aide de réflexions, mais c'est contre la règle. 

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);
}
4
Saurabh Khare

Les valeurs de chaîne sont immuables - donc une fois que vous obtenez une valeur, vous êtes coincé avec elle.

1
ryebr3ad

Les Strings littéraux sont traités spécialement par le langage Java; votre code est à peu près équivalent à:

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 d'autres termes, vous pointez simplement la référence locale errorText sur un autre objet String, ce qui n'affecte rien en dehors de la méthode.

Plus généralement, cependant, Strings sont immuables; il n'y a aucun moyen de les modifier.

0

Vous pouvez réaffecter la référence de chaîne:

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

error = foo(error);
0
sudocode