web-dev-qa-db-ja.com

javaのオブジェクトの交換

Javaは参照渡しであることがわかりましたが、次のコードを実行すると、mainメソッドで文字列がスワップされないのはなぜですか?

static void swap(String s1, String s2){
    String temp = s1;
    s1=s2;
    s2=temp;
}

public static void main(String[] args) {
    String s1 = "Hello", s2 = "world";
    swap(s1, s2);
    System.out.println(s1 + s2);
}
10
sabu

あなたは間違った情報源を研究しました。 Javaは値渡しです。 ここ はもう1つの情報源です。 ここ から、あなたと同様の例についての議論を見つけることができます。 。

10
Mikko Maunu

1。何よりもまず、Javaは_pass by Value_。(つまりコピーで渡す)です。

2。あなたはpassing thereferenceNotObjectメソッドに。

例:

_public class Test{

        private String x;

            public void go(String s){

                this.x = s;

           }

         public static void main(String[] args){

                  Test t = new Test();

                  String a = new String("Bye");

                  t.go(a);


             }
      }
_

上記のコードは、スワッピングがどのように行われるかを示すためではなく、重要なポイントを表示するためのものです。

  • go(String s)メソッドが引数 "a"を渡すことによって呼び出されます _Object reference variable_タイプString パラメータ "s"に、これも _Object reference variable_タイプString、値/コピーによって渡される参照のみ

  • 任意変更はreferenceヒープ上のStringオブジェクトに影響しますが、影響しません _the reference_。

8

メソッドに渡されるのは、オブジェクトの参照のcopyです。したがって、参照を何度再割り当てしても、元の参照は影響を受けません。

これを試して:

static void reverse(StringBuilder builder) {
    builder.reverse();
}

public static void main(String[] args) {
    StringBuilder builder = new StringBuilder("hello");
    System.out.println(builder);
    reverse(builder);
    System.out.println(builder);
}

ただし、以下のメソッドは、渡された元のオブジェクトに何の違いもありません。

static void swap(StringBuilder builder) {
    builder = null;
}
2
adarshr

Javaは参照を値で渡します。呼び出されているメソッドで参照を交換しても、呼び出し元には影響しません。文字列は不変であるため、呼び出し元に表示されるswapメソッドで文字列に対して実行できることは何もありません。

ただし、可変オブジェクトを渡すと、swapで行われたオブジェクトへの変更が元のオブジェクトに反映されることがわかります。

public static void main(String[] args) {
    String a[] = {"hello", "world"};
    swap(a);
    System.out.println(a[0] + " " + a[1]);
}
static void swap(String[] a) {
    String t = a[0];
    a[0] = a[1];
    a[1] = t;
}

これは、配列が可変(つまり、その状態に変更を加えることができる)であり、元のオブジェクトへの参照が(値によって)呼び出されている関数に渡されるために機能します。 swapaのコンテンツを変更すると、同じオブジェクトであるため、呼び出し元のaのコンテンツも変更されます。

1
dasblinkenlight

Javaは常に参照を値で渡します。詳細については、 この回答 をお読みください。ただし、配列またはラッパークラスを介して2つの文字列を交換できます。


編集:

@dasblinkenlightは、配列を使用して2つの文字列を交換する方法を示しています。次に、ラッパークラスの使用例を示します。

public class WrapperString
{
    public String text;

    public WrapperString(String text){this.text = text}

    @Override
    public String toString(){return text;}
}
public static void swap(WrapperString a, WrapperString b)
{
    String temp = a.text;
    a.text = b.text;
    b.text = temp;
}

public static void main(String[] args)
{
    WrapperString s1 = new WrapperString("Hello");
    WrapperString s2 = new WrapperString("World");

    swap(s1, s2);
    System.out.println(s1.text + s2.text);
    // or System.out.println(s1 + s2); since we've already overridden toString()
}

出力:

WorldHello
1
Eng.Fouad

Javaは厳密に値渡しです。

説明の観点から、以下のようにコードを変更してみましょう。

static void swap(String str1, String str2){
String temp = str1;
str1=str2;
str2=temp;
}

public static void main(String[] args) {
String s1 = "Hello", s2 = "world";
swap(s1, s2);
System.out.println(s1 + s2);

}

S1とS2は、文字列オブジェクトのアドレスを保持する参照です。例:S1 = 123、S2 = 234

スワップメソッドを呼び出すと、S1とS2のコピーが作成され、str1とstr2に割り当てられます。

これはstr1 = 123とstr2 = 234になります。

スワップメソッドは、str1とstr2に存在する値のみをスワップします。 (str1 = 234 str2 = 123)一方、S1とS2は同じメモリ位置を指します。

これが、スワップがmainメソッドに反映されない理由です。

0
S.Asha
public static void swap(SwapDate[] t)
    {
     SwapDate temp;;
      temp=t[0];
       t[0]=t[1];
       t[1]=temp;
    }




       public static void main(String args[])throws Exception{

          SwapDate t[]=new SwapDate[5];
           t[0]=new SwapDate(20,8,2015);
           t[1]=new SwapDate(8,8,2015);

           System.out.println("(First object)Account Opnening date :"+" "+t[0].date);
           System.out.println("(second object)Account Opnening date :"+" "+t[1].date);


           swap(t);
           System.out.println("After Swap");

           System.out.println("(First object)Account Opnening date :"+" "+t[0].date);
           System.out.println("(second object)Account Opnening date :"+" "+t[1].date);


           }
0
Om Deshmukh