Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

Stringと配列(参照型???)

メソッドの引数に関しての質問です。
下記の2つのソースで結果が異なるのですが、理解ができません。
【String】で結果が出力されない理由等、ご回答いただけると助かります。

※私の中では、【String】も参照型という認識です。


ソース1(String):
public class Test {
  // "佐藤" と "浩" の2つの文字列を返すメソッド
  public static void getYourName(String a, String b) {
    a = "佐藤";
    b = "浩";
  }

  public static void main(String[] args) {
    String x = " ";
    String y = " ";
    getYourName(x, y);
    System.out.println("名字は" + x + "。");
    System.out.println("名前は" + y + "。");
  }
}

ソース2(配列):
public class Test {
  // "佐藤" と "浩" の2つの文字列を返すメソッド
  public static void getYourName(String[] a) {
    a[0] = "佐藤";
    a[1] = "浩";
  }

  public static void main(String[] args) {
    String x[] = new String[2];
    getYourName(x);
    System.out.println("名字は" + x[0] + "。");
    System.out.println("名前は" + x[1] + "。");
  }
}

結果(ソース1):
名字は 。
名前は 。

結果(ソース2):
名字は佐藤。
名前は浩。


以上、よろしくお願いいたします。

10

回答

6214

閲覧

10件の回答

評価

0

ここなんかどうでしょうか。
http://www.tec-q.com/note/2007/04/_java_13.html

評価

0

>>やまださん
わかりやすい内容のサイトでした。
ありがとうございました。

評価

0

参照型をメソッドの引数にした場合、メソッドの呼び出し元のオブジェクトの内容が変化するとあります。

String型は不変である事から、メソッドの呼び出し元のオブジェクトの内容が変化しない。

という認識であっているのでしょうか。

評価

0

> String型は不変である事から、メソッドの呼び出し元のオブジェクトの
> 内容が変化しない。という認識であっているのでしょうか。

その認識は間違っています。内容が変化しないのは String が自身を変更するメソッドを持っていないからです。

評価

0

逆に、何が変化するのか、という視点からも考えてみては。

評価

0

Javadocには『この値を作成したあとに変更はできません。』と書いてあるのですが・・・。

何が変化するのか。Stringは変化しないのでしょう?
変化するとすれば新しいオブジェクトが生成されるってことでしょうか?

ソース2の配列ではオブジェクトを操作するメソッドが利用されているのでしょうか?
ソース1でもStringを変更するメソッドは利用されておりません。というよりないんですよね。
ということは、Stringは不変だからこそ変化していないのではないのですか?

参照を渡す時に勝手にメソッドが働くのでしょうか。

がーわかりません。

評価

0

最初のソースで値が入らない理由が「Stringが不変」の件でないのは、String以外のクラスで試してみれば分かる。

private static void foo(List l){
l=new ArrayList();
}
private static void bar(List l){
l.clear();
}
public static void main(String... args){
List l=new ArrayList();
l.add("test");
System.out.println(l.isEmpty());
foo(l);
System.out.println(l.isEmpty());
bar(l);
System.out.println(l.isEmpty());
}

ソース1で呼び出し元に返せないのはListでも同じ。
「Stringが不変」というのは、Listの#add()や#clear()にあたるメソッドがない、ということ。

評価

0

Stringと友達な、StringBuilderのほうがわかりやすかったかな。
sb=new StringBuilder();
では呼び出し元のsbを空にできないが、
sb.setLength(0);
なら呼び出し元のsbを空にできる。

評価

0

たまに誤解している人がいますが、CやJavaには引数の参照渡しというものはありません。すべて値渡しです。

Cではポインタを渡すことで関数の中で変数に変化を与えられることから参照渡しと勘違いされることがありますが、実際にはポインタ値(アドレス)を値渡ししていて、関数内でポインタの指してる先のデータを直接書き換えようというアプローチになっています。

Javaも同様です。プリミティブ変数であってもオブジェクト変数であっても変数の指している対象自体を変えることはできません。

Person p = 山田さんインスタンス

となっていた場合、メソッドが p を受け取っても p の指している対象を、鈴木さんインスタンスに変更したり null に変更したりすることはできません。(できないというのは呼び出し元に反映されないという意味です。メソッド内の仮引数(変数)はもちろん変更されます。)

ただし、p インスタンスの状態を変えることはできます。山田さんの右手を挙げさせるとかね。

で、Java の仮引数の扱いに関して、String が特別に扱われるということは一切ありません。

> String型は不変である事から、メソッドの呼び出し元のオブジェクト
> の内容が変化しない。

認識が間違っていると書いたのは、『呼び出し元の』オブジェクトの内容が変化しない、と書かれていたからです。『呼び出し元の』と強調されると、メソッド内ではオブジェクトの内容が変化するように読めませんか? String はそもそもメソッド内であってもオブジェクトの内容を変化させることができません。よって、呼び出し元の内容も変化させることができません。それだけのことなんです。引数渡しとはまったく関係のない話なんです。

評価

0

$氏のサンプルや、@氏の認識が間違っていると書いた理由で概ね理解する事ができた思います。

別スレ立てずに質問したにも関わらずご回答頂き、
感謝致します。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。