web-dev-qa-db-fra.com

Changement de valeur de chaîne Java dans la fonction

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".

24
Yura

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;
    }
}

Une petite leçon sur les références:

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.

34
NullUserException

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.

7
starblue

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.

3
Johannes Wachter

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);
   }
}
3
Aaron Novstrup

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.

1
Prasoon Saurav

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

0
portforwardpodcast