J'ai cette question très délicate ...
void changeString(String str){
str = "Hello world":
}
main(){
String myStr = new String("");
changeString(myStr);
}
Lorsque main
est renvoyé, la valeur est toujours ""
et non "Hello world"
. Pourquoi donc?
Aussi, comment puis-je le faire fonctionner? Disons que je veux que ma fonction changeString
change la chaîne qui devient "Hello world".
Tout le monde a expliqué pourquoi cela ne fonctionne pas, mais personne n'a expliqué comment le faire fonctionner. Votre option la plus simple consiste à utiliser:
String changeString() {
return "Hello world";
}
main() {
String myStr = new String("");
myStr = changeString();
}
Bien que le nom de la méthode soit un abus de langage ici. Si vous deviez utiliser votre idée originale, vous auriez besoin de quelque chose comme:
void changeString(ChangeableString str) {
str.changeTo("Hello world");
}
main() {
ChangeableString myStr = new ChangeableString("");
changeString(myStr);
}
Votre classe ChangeableString
pourrait ressembler à ceci:
class ChangeableString {
String str;
public ChangeableString(String str) {
this.str = str;
}
public void changeTo(String newStr) {
str = newStr;
}
public String toString() {
return str;
}
}
En méthode Java, tout est passé par valeur. Cela comprend des références. Ceci peut être illustré par ces deux méthodes différentes:
void doNothing(Thing obj) {
obj = new Something();
}
void doSomething(Thing obj) {
obj.changeMe();
}
Si vous appelez doNothing(obj)
à partir de main()
(ou ailleurs), obj
ne sera pas modifié dans l'appelé car doNothing
crée une nouvelle Thing
et affecte cette nouvelle référence à obj
dans le cadre de la méthode .
D'autre part, dans doSomething
, vous appelez obj.changeMe()
et cette déréférence obj
- qui a été passée par valeur - et la modifie.
Java utilise un appel appel par valeur startegy pour évaluer les appels.
Autrement dit, la valeur est copiée dans str
. Par conséquent, si vous affectez à str
, cela ne modifie pas la valeur d'origine.
Si le changement de votre String
se produit très souvent, vous pouvez également affecter un StringBuffer
ou StringBuilder
à votre variable, modifier son contenu et le convertir uniquement en String
lorsque cela sera nécessaire.
Développer un peu sur l'excellente réponse de NullUserException , voici une solution plus générale:
public class Changeable<T> {
T value;
public Changeable(T value) {
this.value = value;
}
public String toString() {
return value.toString();
}
public boolean equals(Object other) {
if (other instanceof Changeable) {
return value.equals(((Changeable)other).value);
} else {
return value.equals(other);
}
}
public int hashCode() {
return value.hashCode();
}
}
Le code original de Yura peut ensuite être réécrit comme suit:
void changeString(Changeable<String> str){
str.value = "Hello world":
}
void main() {
Changeable<String> myStr = new Changeable<String>("");
changeString(myStr);
}
Et juste pour le plaisir, la voici dans Scala :
class Changeable[T](var self: T) extends Proxy;
object Application {
def changeString(str: Changeable[String]): Unit = {
str.self = "Hello world";
}
def main(): Unit = {
val myStr = new Changeable("");
changeString(myStr);
}
}
Parce que la référence myStr
est transmise valeur par valeur à la fonction changeString
et que la modification ne soit pas renvoyée à la fonction appelante.
P.S: Je ne suis pas un gars de Java.
Bill, j'ai une solution à votre problème qui utilise une liste comme pointeur en Java!
void changeString(List<String> strPointer ){
String str = "Hello world";
strPointer.add(0, str);
}
main(){
LinkedList<String> list = new LinkedList<String>();
String myStr = new String("");
changeString(list);
myStr = list.get(0);
System.out.println( myStr );
}
Cette réponse nécessite un peu de travail supplémentaire pour insérer et extraire la chaîne de la liste, mais la dernière ligne affichera "Hello world!"
J'espère que cela peut aider les autres aussi!
-Portcast Forward