Question Modification de la valeur de la chaîne Java dans la fonction


J'ai cette question très embarrassante ...

void changeString(String str){
    str = "Hello world":
}

main(){
    String myStr = new String("");
    changeString(myStr);
}

Quand main retourne, la valeur est toujours "" et pas "Hello world". Pourquoi donc?

Comment puis-je le faire fonctionner? Disons que je veux ma fonction changeString pour changer la chaîne il est arrivé à "Hello world".


21
2017-08-15 05:57


origine


Réponses:


Tout le monde a expliqué pourquoi cela ne fonctionnait pas, mais personne n'a expliqué comment le faire fonctionner. Votre option la plus simple est d'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 ChangeableString la classe pourrait être quelque chose comme 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 leçon rapide sur les références:

En méthode Java, tout est passé par valeur. Cela inclut 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) de main() (ou ailleurs), obj ne sera pas changé dans l'appelé parce que doNothing crée un nouveau Thing et assigne cette nouvelle référence à obj  dans le cadre de la méthode.

Par contre, dans doSomething vous appelez obj.changeMe(), et que déréférences obj - qui a été passé par valeur - et le change.


33
2017-08-15 06:08



Java utilise un appel par valeur startegy pour évaluer les appels.

C'est-à-dire que la valeur est copiée dans str, alors si vous affectez à str cela ne change pas la valeur d'origine.


7
2017-08-15 06:00



Si le changement de votre String arrive très souvent, vous pouvez également attribuer un StringBuffer ou StringBuilder à votre variable et modifier son contenu et le convertir uniquement en un String quand cela est nécessaire.


3
2017-08-15 10:26



Expansion 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 alors ê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
2017-08-15 22:02



Parce que la référence myStr est passé par valeur à la fonction changeString et le changement n'est pas répercuté sur la fonction appelante.

P.S: Je ne suis pas un gars de Java.


1
2017-08-15 06:00



Bill, j'ai une solution à votre problème qui utilise une liste comme pointeur dans 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 prend un peu de travail supplémentaire pour insérer et extraire la chaîne de la liste, mais la dernière ligne imprimera "Hello world!"

J'espère que cela peut aussi aider les autres!

-Port Forward Podcast


0
2018-04-15 00:31