ここから本文です

java初心者です。入門書で配列の勉強をしているのですが、ご質問があります。

tak********さん

2017/4/1622:16:33

java初心者です。入門書で配列の勉強をしているのですが、ご質問があります。

public class Main {

public static void main(String[] args){

int [] a = { 1,2,3};

int [] b;

b = a;

b[0] = 100;

System.out.println(a[0]);
}
}

上記を実行しますと、「100」が出力されますが、これが何故だかがいまいち理解することができません。

配列を作成(「int [] score = new int[5];」)したときメモリの中でどのようなことが起きているのか・・・配列変数の宣言によりint[]型変数が、new演算子により配列の実体(要素の集まり)がメモリ上の区間に作成されます。そして、配列変数には5つの要素まるごとではなく、「最初の要素のアドレスが代入されます。」
int[] score = new int[5];を実行した時のメモリ上の様子。
①int 型の要素を5つ持つ配列がメモリ上に作成される。
②int[]型の配列変数 score がメモリ上に作成される。
③score に配列の先頭要素のアドレスが代入される。
ソースコードの変数aにメモリのアドレス(住所)8832が入っていたとした場合、5行目でコピーされているのは、この8832になります。その結果、変数 b は変数 a と同じ配列を参照することになります。
よって、a[0]とb[0]は、まったく同一のものを指していることになります。この状態で「b[0] = 100;」を実行することは「a[0]=100;」と同じです。当然、7行目では100が出力されます。

入門書に書いてあった所で理解できなかった部分なんですが、実際には図が書いてあったりしたのでうまく説明できてないかもしれません。。。

配列変数 score は「配列の実体は8832 番地にあります」と指し示す動作をしていることになります。このことを「参照」と呼びます。←この意味もあまりよく分かりませんでした。配列の実体とは一体なんのことなのでしょうか。。。

閲覧数:
138
回答数:
2
お礼:
25枚

違反報告

ベストアンサーに選ばれた回答

アバター

ID非公開さん

2017/4/1622:49:16

int [] a = { 1,2,3};
で配列aの内容が1,2,3になる

この時、変数aが示しているのは
1,2,3が入ったメモリ上のある部分の位置情報であり

1,2,3そのものではない

int [] b;
で、bという変数が宣言されるが
このbにはint型の変数の配列が入ったメモリ上の位置情報が入れられるようになっている


b = a;

すると、bの中にはaの中に入っているメモリ上の1,2,3の入った位置の情報が入る


この時、

b[0]=100

とすると
bの中に入っている位置情報の先にある配列1,2,3の0番目が100に書き換えられる
bの中に入っている位置情報はaの中に入っている位置情報と同じ

bの中に入っている位置情報の先にある配列の0番目は
aの中に入っている位置情報の先にある配列の0番目と同じ

よって、a[0]を表示すると100になる

  • 質問者

    tak********さん

    2017/4/1710:00:34

    ご丁寧な回答ありがとうございます。
    大方理解することができたんですが、まだ分からないことが一点だけあります。
    入門書に書いてあったのですが、「(int [] score = new int [5];)とした場合、配列変数には5つの要素まるごとではなく、「最初の要素のアドレス」が代入されます。」
    つまりint [] a = { 1,2,3};の場合ですと、0番目の要素(1)が格納されているメモリのアドレスを配列変数 a は示しているということなのでしょうか?

  • その他の返信(1件)を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

ベストアンサー以外の回答

1〜1件/1件中

2017/4/1810:39:31

>つまりint [] a = { 1,2,3};の場合ですと、0番目の要素(1)が格納されているメモリのアドレスを配列変数 a は示しているということなのでしょうか?

それはC言語の話。Javaではそうなりませんし、もしそう書いてあるなら、その作者は無知すぎるか分かりやすくするために嘘を教えているものと思われます。

というのも、実は配列もObjectクラスを継承する特殊なclassのインスタンスだからです。
その証拠に、配列はgetClass()でクラスを取得できますし、Objectにキャストすることもできますし、toString()すら可能です。

int[] a={1,2,3}というのは、int型の変数を3つ持つ配列クラスのインスタンスを生成し、そのクラスインスタンスのアドレスをaに代入していますので、int配列の先頭のintのアドレスを代入しているのではありません。
なお、配列クラスは[0]などを用いて内部に保持する変数にアクセスできますが、これは仮想的な特殊クラスのための例外措置です。

さて、このことを踏まえて解説します。
int [] a = { 1,2,3};
というのは
配列型クラスのインスタンスを生成し、その中に3つのint型変数を保持し、できた配列インスタンスアドレスをaに代入するという意味になります。
b = a;
により、aと同じ配列インスタンスアドレスがbに代入されました。
b[0] = 100;
というのは、配列インスタンスの3つの変数の最初の変数に100を代入しているので、配列インスタンスの最初のint変数が100に書き換わります。
よってa[0]も100となります。

このへんは普通のクラスに書き換えて考えるとわかりやすいかもしれませんので、ちょっと書いてみますね。
class Hairetsu{
int a0;
int a1;
int a2;
public Hairetsu(int a0,int a1,int a2){
this.a0=a0;
this.a1=a1;
this.a2=a2;
}
}
Hairetsu a=new hairetsu(1,2,3);
hairetsu b;
b=a;
b.a0=100;
System.out.println(a.a0);

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる