web-dev-qa-db-ja.com

メソッドに渡されるStringオブジェクトの値を変更できますか?

次の質問が見つかりました Is Java "pass-by-reference" or "pass-by-value"?

私はほとんどすべてを読みましたが、foo(-)メソッドでStringvalue? (多分参照もそうでないかもしれませんが、私には関係ありません)。

void foo(String errorText){ 
    errorText="bla bla";
}

int main(){ 
    String error="initial"; 
    foo(error); 
    System.out.println(error);
}

見たい bla blaコンソールで。出来ますか?

25
merveotesi

メソッドが現在宣言されているため、errorTextfooの値を変更することはできません。文字列errorTextの参照をfooに渡しても、Java Stringsは不変であり、変更できません。 。

ただし、StringBuffer(またはStringBuilder)を使用できます。これらのクラスは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);
    }
}

他の解決策は、ラッパークラスを使用する(String参照を保持するクラスを作成し、fooで参照を変更する)、または単に文字列を返すことです。

38
Jack Edmonds

メソッドの戻り値を使用するか、ラッパークラスを作成します。

値を返すようにしてください:

String foo(String errorText){ 
    return "bla bla";
}

int main(){ 
    String error="initial"; 
    error = foo(error); 
    System.out.println(error);
}

値をオブジェクトにラップします。

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

はい、あなたは反射の助けを借りてこれを変更することができますが、それはルールに反しています。

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);
}
4
Saurabh Khare

文字列値は不変です。つまり、一度値を取得すると、それで行き詰まります。

1
ryebr3ad

リテラルStringsは、Java言語によって特別に処理されます。コードはおおよそ次のコードと同等です:

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

つまり、ローカル参照errorTextを別のStringオブジェクトに向けているだけで、メソッドの外部には影響を与えません。

ただし、より一般的には、Stringsは不変です。それらを変更する方法はありません。

0

文字列参照を再割り当てできます。

String foo(String err) {
  return "bla blah"
}

error = foo(error);
0
sudocode