2016-04-09 8 views
0
class OtherObject { 
    String innerString; 
    OtherObject(String x) {innerString = x;} 
} 

class Playground { 
    public static void mutate(OtherObject toMutate) { 
     toMutate.innerString = toMutate.innerString.substring(toMutate.innerString.length()/2); 
    } 

    public static void mutate(String toMutate) { 
     toMutate = toMutate.substring(toMutate.length()/2); 
    } 

    public static void main(String[] args) { 
     String helloWorld = new String("Hello, World!"); 
     OtherObject helloWorld2 = new OtherObject("Hello, World!"); 
     mutate(helloWorld); 
     mutate(helloWorld2); 

     System.out.println(helloWorld); 
     System.out.println(helloWorld2.innerString); 
    } 
} 

、私はこの方法mutateを介して2つのオブジェクトを設定していると、この出力に示すように、オブジェクトの一方のみが、変更された:私の記憶が正しければのでこの例でString helloWorldが変更されないのはなぜですか?この例では

Hello, World! 
World! 

Process finished with exit code 0 

これは私を混乱させる:

  • オブジェクトに渡すと、参照を渡すので、返さなくてもオブジェクト自体を変更することができます
  • これは、私がArrayListを渡すことができる同じ理由です。同じArrayListを返さずに、それを前のArrayListに代入することなく、mainにそれを操作します。
  • 文字列はオブジェクトです。

なぜ文字列helloWorldが変更されませんでしたか?

+0

文字列は変更できません。変更できません。 – chrylis

答えて

2

あなたはこのことについて尋ねることが表示されます。

public static void mutate(String toMutate) { 
    toMutate = toMutate.substring(toMutate.length()/2); 
} 

toMutate変数が文字列オブジェクトへの参照を含むローカル変数です。 にのみ割り当て、はローカル変数を変更します。参照元の呼び出し元メソッドの変数は変更されません。

技術的な答えは、Javaの引数の受け渡しは「値渡し」であり、「参照渡し」ではないということです。文字列を渡すときは、文字列参照を値渡ししています。呼び出し元の文字列参照を保持する変数への参照を渡すことはありません。あなたはJavaでそれを行うことはできません。

つまり、void mutate(String)をJavaで実装することはできません。メソッドのシグネチャは異なる必要があり、セマンティクスと使用方法は異なります。


メソッドに渡されるオブジェクトは、あっても戻らずに、オブジェクト自体を変更することができるため、参照を渡しています。

間違いがあります。オブジェクトはに変更されていればに変更できます。 Stringオブジェクトは不変です。それは特に変更することができないように設計されています。

変更可能な「文字列のような」オブジェクトを変更したい場合は、StringBuilderまたはStringBufferオブジェクトを使用できます。 (詳細についてはjavadocsを参照してください。)

-1

文字列はJavaでは不変なので、つまり、一度作成されると、同じStringオブジェクトを変更することはできません。内部的には、Javaはjava.lang.StringBufferを使用して、Stringオブジェクト自体を変更するのではなく、文字列を変更します。

これは、いったんJavaで作成された文字列は、それ自体では変更できないためです。別のStringオブジェクトがmutate(String)メソッドで作成されます。そしてあなたの元のストリングはそのままです。

0

これらの例で何が変更されているかを正確に考える必要があります。あなたは

toMutate.innerString = toMutate.innerString.substring(toMutate.innerString.length()/2) 

を書くとき

あなたはOtherObjectのインスタンスのフィールドinnerStringを変更しています。これは、オブジェクトを突き詰めることを意味します。フィールドを変更します。あなたが任意のオブジェクトのフィールドを変更していない

toMutate = toMutate.substring(toMutate.length()/2); 

を書く一方

、。あなたがしているのは、変数の再割り当てです。 Javaは常に値渡しであるため、オブジェクト参照が渡されても、この行は何の効果もありません。