こんにちは。ECF Techブログ
担当 Michiharu.Tです。
Javaプログラミング入門記事の第6章をお送りいたします。
第6章のテーマは「メソッド」です。
第6章は2回のパートに分けて掲載します。今回はPart2です。
本連載の初回および章立ての一覧については下記のリンクから確認できます。
解説動画
2024/01/19 解説動画を掲載しました。
6-4 メソッド活用のポイント
6-4-1 メソッドとスコープ
複数のメソッドを扱うようになりましたので、メソッドのスコープについて確認しておきたいと思います。結論からお伝えしますと、メソッド内で定義された変数の利用可能な範囲は定義されたメソッド内のみです。プログラム例を示します。
プログラム例
public class Main { public static void main(String[] args) { int x = tasizan(10, 8); int y = hikizan(16, 4); System.out.println(x); System.out.println(y); } public static int tasizan(int x, int y){ int ans = x + y; return ans; } public static int hikizan(int x, int y){ int ans = x - y; return ans; } }
実行結果
18 12
解説
次の3つのメソッドが定義されています。
- 2つの値を引数として受け取って、足し算した結果を返すtasizanメソッド
- 2つの値を引数として受け取って、引き算した結果を返すhikizanメソッド
- 上記2つのメソッドを呼び出すmainメソッド
各変数・引数の利用可能な範囲はそれぞれ次のとおりです。各変数・引数の下線の色が利用可能な範囲を表す枠の色と一致しています。
ポイントの1つがx
とy
です。
- mainメソッド内で定義された変数
x
とy
- tasizanメソッド内で定義された引数
x
とy
- hikizanメソッド内で定義された引数
x
とy
の利用可能な範囲はすべてそれぞれのメソッドブロック内のみとなります。そのため、変数名が重複することによるエラーが発生することはありません。
tasizanメソッドとhikizanメソッドに宣言されている変数ans
も同様です。2つのメソッドで変数名の重複によるエラーが発生しないため、「答えを入れておく変数はans
にする」といった統一感のあるプログラムを書くことができます。
6-4-2 return文忘れに注意
戻り値の型をvoid以外で定義しているメソッドは、必ず値を返す必要があります。次のようなケースでreturn文の書き忘れにならないように注意しましょう。
プログラム例
public class Main { public static void main(String[] args) { int a = calcTax(1000); } public static int calcTax(int price) { if(price < 0) { System.out.println("1以上を指定してください"); } else { //消費税を加算して値を返す int ans = (int)(price * 1.1); return ans; } } }
実行結果
Main.java:13: エラー: return文が指定されていません } ^ エラー1個
解説
calcTaxメソッドは金額を引数で受け取り、消費税を加算した税込価格を戻り値として返すメソッドです。税込価格は端数切捨てとなります。このプログラムは6行目のif文に入るとreturn文を返すことができず、コンパイルエラーとなります。分岐の制御構文がある場合などは注意が必要となります。
6-5 メソッド呼び出しと評価
メソッド呼び出し時の戻り値は、3章の演算でご紹介した評価の考え方で理解をすることで、書き方の幅が広がります。プログラム例をご紹介します。
プログラム例
public class Main { public static void main(String[] args) { System.out.println( tashizan( kakezan(8,4), kakezan(5,5) ) ); } //たし算を行なうメソッド public static int tashizan(int x, int y) { return x + y; } //かけ算を行なうメソッド public static int kakezan(int x, int y) { return x * y; } }
実行結果
57
解説
3行目は、メソッド呼び出しの中にメソッド呼び出しが存在する一見複雑な文になっていますが、下図のように考えると処理のイメージがしやすくなります。
図のように、メソッド呼び出しの部分は戻り値に置きかわります。動作の順番は
kakezan(8,4)
でkakezanメソッドが呼び出され、戻り値32
に置きかわる。kakezan(5,5)
でkakezanメソッドが呼び出され、戻り値25
に置きかわる。tashizan(32,25)
でtashizanメソッドが呼び出され、戻り値57
に置きかわる。57
がSystem.out.println
により、画面に表示される。
となります。
6-6 参照型とメソッド
メソッドの引数や戻り値の型には、参照型を取ることもできます。配列を扱うメソッドを例に動作を確認します。
6-6-1 配列を引数にとるメソッド
始めに配列を引数にとるメソッドの例です。プログラムを示します。
プログラム例
public class Main { public static void main(String[] args) { int[] array = {1,2,3,4,5}; //配列を引数として渡す arrayDisplay(array); } public static void arrayDisplay(int[] target) { for( int i = 0; i < target.length; i++ ) { System.out.println(target[i]); } } }
実行結果
1 2 3 4 5
解説
mainとarrayDisplayの2つのメソッドがあります。mainメソッドでは配列arrayを宣言し、5行目でarrayDisplayメソッドに引数として渡しています。ここで引数として渡されるのは配列のアドレスです。したがって、5行目で呼び出されたarrayDisplayメソッドは下図の状態となって開始されます。
arrayDisplayメソッドを実行している間、引数targetはmainメソッドの変数arrayと同じ配列を指していますので、各要素の値(1~5)が表示されることになります。
6-6-2 配列を戻り値として返すメソッド
次に配列を戻り値として返すメソッドの例です。プログラムを示します。
プログラム例
public class Main { public static void main(String[] args) { int[] array = createArray(); //配列の各要素を表示 for( int i = 0; i < array.length; i++ ) { System.out.println(array[i]); } } //配列を生成し、戻り値として返す public static int[] createArray() { int[] data = {2,4,6,8,10}; return data; } }
実行結果
2 4 6 8 10
解説
createArrayメソッドの戻り値型がint[]
となっています。
mainメソッドの最初でcreateArrayメソッドを呼び出しています。createArrayメソッドが呼び出され、戻り値が返る様子を下図に示します。
図に示すとおり、createArrayメソッドから戻り値として返されるのは、12行目で生成された配列のアドレスです。したがって、createArrayメソッドから戻り値が返ってきた後は次のようになっています。
mainメソッド側の変数arrayがcreateArrayメソッドで生成した配列を指し示していますので、6行目以降のfor文では配列の各要素の値が表示されることになります。
6-7 コマンドライン引数
ここで、mainメソッドについて少し紐ときをしておきたいと思います。
これまでmainメソッドの定義部分については
public static void main(String[] args) {
と呪文のように書いてきましたが、メソッドの文法に照らすと
void
は戻り値型main
はメソッド名String[] args
は引数
ということがわかります。
戻り値がvoid
で、メソッド名がmain
なのはなんとなく納得できるところですが、引数がString[] args
というのはどういうことなのでしょうか?
実はmainメソッドにも引数を渡すことができます。タイミングはプログラムの実行時になります。これについては動作を体感した方が分かりやすいですので、先にプログラムと実行例を示します。
プログラム例
public class Main { public static void main(String[] args) { System.out.println( args[0] ); System.out.println( args[1] ); } }
実行結果(実行時入力を含む)
> java Main Hello Java Hello Java
>
の行は、実行時の入力コマンドであることを示しています。
解説
ポイントはプログラム実行時の入力方法です。プログラム実行時に次のように記述することで、mainメソッドの引数に値を渡すことができます。
java クラス名 値1 値2 値3 ....
- 値部分は半角スペースでそれぞれ区切ります。
- コマンドライン上から渡す引数なので、コマンドライン引数と言います。
次にプログラム実行時のイメージを示します。
- 実行時に渡された引数(ここでは
Hello
とJava
)の数に応じた配列が用意され、mainメソッドの引数args
に配列のアドレスが格納されます。 - その配列にコマンドライン引数が格納されます。
args[0]
、args[1]
などと記述することで、コマンドライン引数の内容を利用できます。
String[]
以外にすることはできません。