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?
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 String
s 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.
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());
}
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);
}
Les valeurs de chaîne sont immuables - donc une fois que vous obtenez une valeur, vous êtes coincé avec elle.
Les String
s 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, String
s sont immuables; il n'y a aucun moyen de les modifier.
Vous pouvez réaffecter la référence de chaîne:
String foo(String err) {
return "bla blah"
}
error = foo(error);