回答編集履歴

1

補足説明を追記しました。

2016/09/21 11:50

投稿

退会済みユーザー
test CHANGED
@@ -97,3 +97,235 @@
97
97
 
98
98
 
99
99
  ```
100
+
101
+
102
+
103
+ ###参照について(追記)
104
+
105
+ Q. 参照型変数とプリミティブ型変数の違いはなんですか?
106
+
107
+ A. 変数は次の種類があります。
108
+
109
+
110
+
111
+ ・プリミティヴ型変数(値そのものが格納される変数)
112
+
113
+ ・参照型変数(配列とオブジェクトを参照する。参照型変数の中身はint型の値)
114
+
115
+ ・型変数(ジェネリクスで使用する。議論の対象外なので説明を省略します)
116
+
117
+
118
+
119
+ 参照型変数に格納する整数値は、ヒープ領域に格納されたオブジェクトの本体を指すために使う。
120
+
121
+ ヒープ領域は大きなメモリ領域で、その中に自由にオブジェクトを割り当てて使える。
122
+
123
+
124
+
125
+ Q. 参照型変数の中身を見ることが来ますか?
126
+
127
+ A. System.identityHashCode(); を使うと見ることができます。2つの参照型変数の値が同じなら、同じオブジェクトを指します。
128
+
129
+
130
+
131
+ **参照がnullの場合**
132
+
133
+ ```Java
134
+
135
+ int[] a = null;
136
+
137
+ int hash = System.identityHashCode(a);
138
+
139
+ System.out.println(hash);
140
+
141
+ ```
142
+
143
+ a はnull。参照がないので 0 が表示されます。
144
+
145
+
146
+
147
+ **参照に配列を割り当てる**
148
+
149
+ ```Java
150
+
151
+ a = new int[] {1,2,3,4,5,6};
152
+
153
+ hash = System.identityHashCode(a);
154
+
155
+ System.out.println(hash);
156
+
157
+ ```
158
+
159
+ 配列をnew すると、ヒープに int型 6 個分の領域を割り当てる。
160
+
161
+ 割り当てたint型 6 個を、それぞれ、1, 2, 3, 4, 5, 6 に初期化する。
162
+
163
+ ヒープの配列への参照値(数値)を参照型変数 a に代入する。
164
+
165
+
166
+
167
+ a (nnnnnnn) ———>  配列の本体 | 1 2 3 4 5 6 |
168
+
169
+
170
+
171
+ **別の参照に参照を代入する**
172
+
173
+ ```Java
174
+
175
+ int[] b = null;
176
+
177
+ b = a;
178
+
179
+ hash = System.identityHashCode(b);
180
+
181
+ System.out.println(hash);
182
+
183
+ ```
184
+
185
+ b には a の参照値(nnnnnnn)が代入される。
186
+
187
+ 代入によって b が a そのものを指すわけではない。(重要)
188
+
189
+ a と b は何の関係もなく、それぞれがヒープの同じ配列を指しているだけ。
190
+
191
+
192
+
193
+ **参照を比較する**
194
+
195
+ ```Java
196
+
197
+ boolean isSame = a == b;
198
+
199
+ System.out.println(isSame);
200
+
201
+
202
+
203
+ isSame = System.identityHashCode(a) == System.identityHashCode(b);
204
+
205
+ System.out.println(isSame);
206
+
207
+ ```
208
+
209
+ a == b は実は、参照値(nnnnnnn)を整数比較しているだけ。
210
+
211
+
212
+
213
+ ###メソッドの引数の有効範囲(追記)
214
+
215
+
216
+
217
+ **プリミティヴ型 k が引数の場合**
218
+
219
+ ```Java
220
+
221
+ static void change(int k) {
222
+
223
+ k = 7;
224
+
225
+ }
226
+
227
+ ```
228
+
229
+ メソッドが呼ばれると、ローカル変数 k がとられる。(k は実引数とはなんの関係もない)
230
+
231
+ k に実引数の値 10 がコピーされる。
232
+
233
+ k に 7 を代入する。
234
+
235
+ メソッド退出時に k を破棄する。このメソッドは何も有意義なことはしない。
236
+
237
+
238
+
239
+ **参照型 x2[] が引数の場合**
240
+
241
+ ```Java
242
+
243
+ static void change1(int[] x2) {
244
+
245
+ x2[0] = 100;
246
+
247
+ }
248
+
249
+ ```
250
+
251
+ メソッドが呼ばれると、ローカル変数 x2 がとられる。(x2 は実引数とはなんの関係もない)
252
+
253
+ x2 に実引数の参照値(nnnnnn)がコピーされる。
254
+
255
+ 参照値が参照する配列の本体の要素0の値は 6。要素0の値を 100 に置き換える。
256
+
257
+ メソッド退出時に x2 を破棄する。
258
+
259
+ x2 は破棄されるが、ヒープの配列の本体は変更されたまま。このメソッドは有意義なことをしている。
260
+
261
+
262
+
263
+ **参照型 x[] が引数の場合**
264
+
265
+ ```Java
266
+
267
+ static void change1(int[] x) {
268
+
269
+ x = new int[] {11,12,13,14,15};
270
+
271
+ }
272
+
273
+ ```
274
+
275
+ メソッドが呼ばれると、ローカル変数 x がとられる。(x は実引数とはなんの関係もない)
276
+
277
+ x に実引数の参照値(nnnnnn)がコピーされる。
278
+
279
+ 配列をnew する。ヒープに int型 5 個分の領域を割り当てる。
280
+
281
+ 割り当てたint型 5 個を、それぞれ、11, 12, 13, 14, 15 に初期化する。
282
+
283
+ ヒープの配列への参照値(mmmmmm)を参照型変数 x に代入する。
284
+
285
+ 今や x の参照値は、別の配列を指すようになった。
286
+
287
+ メソッド退出時に x を破棄する。
288
+
289
+ 参照値(mmmmmm)が指す配列の本体を誰も参照しないので、GCの対象になる。
290
+
291
+ このメソッドは何も有意義なことはしない。
292
+
293
+
294
+
295
+ **参照型 x[] が引数で勝つ返り値に参照を返す場合**
296
+
297
+ ```Java
298
+
299
+ static int[] change3(int[] x) {
300
+
301
+ return new int[] {11,12,13,14,15};
302
+
303
+ }
304
+
305
+ ```
306
+
307
+ メソッドが呼ばれると、ローカル変数 x がとられる。(x は実引数とはなんの関係もない)
308
+
309
+ x に実引数の参照値(nnnnnn)がコピーされる。
310
+
311
+ しかし x を使わずに、新たな配列を生成して、その参照をメソッドの返り値として返す。
312
+
313
+
314
+
315
+ 配列をnew する。ヒープに int型 5 個分の領域を割り当てる。
316
+
317
+ 割り当てたint型 5 個を、それぞれ、11, 12, 13, 14, 15 に初期化する。
318
+
319
+ ヒープの配列への参照値(mmmmmm)を返り値として返す。
320
+
321
+ メソッド退出時に x を破棄する。
322
+
323
+ メソッドの返り値を実引数 x に代入すれば、x の配列が丸ごと入れ替わる。
324
+
325
+ このメソッドは値を返すことで有意義なことをしている。
326
+
327
+
328
+
329
+ 説明は以上です。質問は受け付けます。気軽にどうぞ。
330
+
331
+