web-dev-qa-db-ja.com

Java関数の文字列値の変更

とても厄介な質問があります...

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

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

mainが返されても、値は""ではなく"Hello world"。何故ですか?

また、どのように機能させるのですか?関数changeStringで取得した文字列を「Hello world」に変更するとします。

27
Yura

なぜそれが機能しないのか誰もが説明しましたが、それを機能させる方法を誰も説明しませんでした。あなたの最も簡単なオプションは使用することです:

_String changeString() {
    return "Hello world";
}

main() {

    String myStr = new String("");
    myStr = changeString();
}
_

メソッド名はここでは誤称ですが。オリジナルのアイデアを使用する場合、次のようなものが必要になります。

_void changeString(ChangeableString str) {
    str.changeTo("Hello world");
}

main() {

    ChangeableString myStr = new ChangeableString("");
    changeString(myStr);
}
_

ChangeableStringクラスは次のようになります。

_class ChangeableString {
    String str;

    public ChangeableString(String str) {
        this.str = str;
    }

    public void changeTo(String newStr) {
        str = newStr;
    }

    public String toString() {
        return str;
    }
}
_

リファレンスに関する簡単なレッスン:

Javaメソッドでは、すべてが値で渡されます。これには参照が含まれます。これは、次の2つの異なるメソッドで説明できます。

_void doNothing(Thing obj) {
    obj = new Something();
}

void doSomething(Thing obj) {
    obj.changeMe();
}
_

doNothing(obj)からmain()を呼び出す場合(またはそのことについてはどこでも)、objは呼び出し先で変更されません。これは、doNothingが新しいThingを作成し、その新しい参照をobjに割り当てるためです- メソッドのスコープ内

一方、doSomethingではobj.changeMe()を呼び出しており、値によって渡されたobjを逆参照して変更します。

35

Javaは、呼び出しを評価するために 値による呼び出し 戦略を使用します。

つまり、値はstrにコピーされるため、strに割り当てても、元の値は変更されません。

7
starblue

Stringの変更が頻繁に発生する場合は、StringBufferまたはStringBuilderを変数に割り当て、その内容を変更して、必要な場合にのみStringに変換することもできます。

3

少し拡張 NullUserExceptionの優れた答え 、より一般的な解決策は次のとおりです。

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

Yuraの元のコードは、次のように書き換えることができます。

void changeString(Changeable<String> str){
   str.value = "Hello world":
}

void main() {
   Changeable<String> myStr = new Changeable<String>("");
   changeString(myStr);
}

そして、面白くするために、ここでは 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

参照myStrは値によって関数changeStringに渡され、変更は呼び出し元の関数に反映されないためです。

PS:私はJava男ではありません。

1
Prasoon Saurav

ビル、私はリストを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 );
}

この回答では、文字列を挿入してリストから取り出すのに少し余分な作業が必要ですが、最後の行には「Hello world!」と表示されます。

これが他の人にも役立つことを願っています!

-ポート転送ポッドキャスト

0