【Java】メソッドの引数を配列にする方法と注意点!メソッドに配列変数を渡す値はメモリのアドレス!?
通常の変数と同じように配列をメソッドに渡すことができます。配列をメソッドに引数として渡すといっても、実際はメモリ内の配列のアドレスが渡されるだけです。
ここでは、Javaのメソッドに引数として配列を渡す方法と、メソッドから配列を返す方法について学びます。
メソッドにパラメータを渡す
一般的な変数(例:整数型の変数)をメソッドに渡すと、その引数はパラメータ変数に格納されます。
メソッド内の変数を変更してもメソッド外の引数の値が変更されるわけではありません。
つまり、メモリ(参照アドレス)ではなく、引数に実際の値が渡されます。
これは、「値渡し」と呼ばれます。
下記のサンプルを見てみましょう
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Main { public int sum(int allNum, int add) { allNum = allNum + add; return allNum; } public static void main(String[] args) { Main ex = new Main(); int allNum = 10; ex.sum(allNum, 5); System.out.println("total=" + allNum); } } |
出力結果
allNum= 10
変数ではなく引数の値を渡していることに注意してください!!メソッドパラメータの変数名は同じでも違っていてもよく、プログラムは同じように機能します。
メソッドsumでは、allNumの値とaddの値を加算し、その値をローカル変数allNumに割り当て、allNumの新しい値を返します。
コードを実行すると、mainメソッドの変数allNumが変更されていないため、allNum = 10が出力されます。
変更された値を取得するにはどうすればいいのでしょうか?
戻り値をmainのallNumに割り当てればOKです。
上のサンプルの9行目:ex.sum(allNum, 5);を下記の様に修正してみましょう
1 |
allNum= ex.sum(allNum、5); |
出力結果
allNum= 15
Javaの配列とは
Arrayは、同じデータ型の値を複数格納することができるオブジェクトです。
int型の変数を3つの配列にしてみます。
1 |
int[] nums = new int[3]; |
配列は[]、intで型を定義し、メモリが3つの要素に割り当てられます。
変数numsは、配列が割り当てられたオブジェクトを参照してますので、System.out.println(nums);などの変数を出力する時は[I @ 92e922]のように、参照先(メモリのアドレス)を取得して出力しているのです。
配列の要素にアクセスするには、nums [0]のように書きます。
2番目の配列要素にアクセスするにはnums [1]のようにすればアクセスできます。
Javaは配列をストレージのブロックとして見ており、そのストレージの先頭(最初の要素)にアクセスするには、数値+オフセット0と指定します。次の要素にアクセスするには、数値+オフセット1と指定します。
この場合オフセット1は、intに格納されている要素のサイズの事を指します。なので、オフセット1は1倍のintサイズで、次のオフセットは2倍のintサイズになります。
したがって下記のように実装すれば、値を割り当た後に各要素の値を出力する事ができます。
1 2 3 4 |
nums[0] = 1; nums[1] = 2; nums[2] = 3; System.out.println(''nums= '' + nums[0] + '' '' + nums[1] + '' '' + nums[2]); |
出力結果
nums=1 2 3
配列をメソッドに渡す
配列の変数がメモリのアドレスを持っている事を考えながら、メソッドに配列を渡すとどうなるか見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class Main { public int sum(int[] x) { x[0] = x[0] + 1; x[1] = x[1] + 1; x[2] = x[2] + 1; return x[0] + x[1] + x[2]; } public static void main(String[] args) { Main ex = new Main(); int[] nums = new int[3]; nums[0] = 1; nums[1] = 2; nums[2] = 3; System.out.println("nums= " + nums[0] + " " + nums[1] + " " + nums[2]); int allNum = ex.sum(nums); System.out.println("nums= " + nums[0] + " " + nums[1] + " " + nums[2]); System.out.println("allNum=" + allNum); } } |
出力結果
nums= 1 2 3
nums= 2 3 4
allNum=9
このコードでは、mainメソッドがMainクラスのインスタンスを割り当て、int型でサイズが3の配列を宣言し、各配列要素に値を入れてます。
次に、配列がメソッドに渡されます
これはメモリ(参照先)のアドレスであり、そのアドレスがメソッドに渡されて配列のローカル変数xに割り当てられています。
int型の配列をパラメータに指定しないと受け取れませんので注意してください。
次に、メソッドではローカル変数x要素が変更されます。ただし、ローカル変数xは配列のアドレス(参照先)があるため、実際には、数値とまったく同じアドレス(参照先)に変更しています。
2人が共有する郵便受けのような場所をイメージください。どちらかの人が手紙を取り出したりしたら、その郵便受けは共有しているので、もう一人の人にも影響してしまいます。
したがって、メインメソッドに戻って配列の内容を出力すると、メソッドで変更された値が入っています。
Ryotin
現役フリーランスエンジニアです。使ってるエージェントはフライテック!得意言語はJava。月収は75万円。SESのフリーランスではこれ以上稼ぐのは厳しそう...とはいってもサラリーマンの時より倍の収入だから家族も喜んでるけどね!