2019/02/06
sponsored link
文字列を返す
前回、引数に渡された値が3で割り切れるかどうかを調べるメソッドを作りました。
3で割り切れれば戻り値としてtrueを返し、割り切れなければfalseを返すようにし、そのメソッドをif文の条件式の中に入れることで、割り切れる場合と割り切れない場合とに分岐させて結果を出力するプログラムでした。
こんなやつです。↓
ReturnTest.java
public class ReturnTest{ public static void main(String[] args){ int a = 23165247; if( isMultipleOf3(a) ){ System.out.println(a + "は3で割り切れます"); }else{ System.out.println(a + "は3で割り切れません"); } } public static boolean isMultipleOf3(int n){ boolean result; result = ( n % 3 == 0 ) return result; } }
一応、思った通りには動いているのですが、もっと戻り値の仕組みの理解を深める為にも、今回はこのclassを改造したいと思います。
これが元々のisMultipleOf3メソッドの定義部分です。
public static boolean isMultipleOf3(int n){ boolean result; result = ( n % 3 == 0 ); return result; }
しつこいようですが、このメソッドは引数に渡された値が3で割り切れればtrueを返し、割り切れなければfalseを返すメソッドです。
前回はその戻り値のboolean(trueかfalse)を使って、mainメソッド内でif文で分岐させて「3で割り切れます」とかっていう文字列を作らせていましたが、今回はこのメソッド自体に結果の文字列も生成する機能を持たせようと思います。
つまり、trueかfalseを返すのではなく、「15は3で割り切れます」みたいな文字列(String型変数)を返すようにします。
Stringを返すメソッド
戻り値に文字列を返すので、戻り値の型はStringです。前回のは戻り値の型がbooleanだったので、書き換えます。
public static String isMultipleOf3(int n){
}
これで、戻り値としてStringを返すメソッドですよ、という定義になりました。
メソッド名が「isMultipleOf3」です。実はこの「is○○○」というメソッド名は戻り値がboolean型のメソッドにつける形なんです(慣習みたいなものです)。戻り値がbooleanじゃないのにこのメソッド名はちょっとおかしいのですが、ここではこのまま行かせて下さい。
メソッドの中身は一から作りなおします。まず戻り値に返す文字列を保持するString型変数resultMessageを宣言します(空の文字列で初期化)。
public static String isMultipleOf3(int n){
String resultMessage = "";
}
そのString変数resultMessageに、if文を使って、3で割り切れるかどうかの文字列を入れましょう。
public static String isMultipleOf3(int n){ String resultMessage = ""; if(n % 3 == 0){ resultMessage = n + "は3で割り切れます"; }else{ resultMessage = n + "は3で割り切れません"; } }
そして、その文字列を入れたresultMessageをreturnします。
public static String isMultipleOf3(int n){
String resultMessage = "";
if(n % 3 == 0){
resultMessage = n + "は3で割り切れます";
}else{
resultMessage = n + "は3で割り切れません";
}
return resultMessage;
}
これでisMultipleOf3メソッドの定義はOKです。引数に渡された値(n)が3で割り切れれば、「nは3で割り切れます」という文字列を戻り値として返し、引数に渡された値(n)が3で割り切れなければ「nは3で割り切れません」という文字列を戻り値として返します。
さて、文字列を返してくるメソッドをどう使えばいいでしょうか?こうしましょう。
public class ReturnTest{
public static void main(String[] args){
System.out.println(isMultipleOf3(123456789));
}
public static String isMultipleOf3(int n){
/*省略*/
}
}
printlnメソッドの引数に、isMultipleOf3メソッドをぶち込みました。こんな場所ででも呼ばれるとreturnされた値に置き換わります。
つまり、isMultipleOf3メソッドが返した文字列がprintlnメソッドにより画面に出力されるわけです。上記の例では123456789を渡しています。これを実行すると、
バッチリですね。
戻り値の型によって変わるそのメソッドの使い方
前回はisMultipleOf3メソッドはtrueかfalseを返すメソッドだったので、mainメソッド内でその結果から文字列を作る作業をする必要がありましたが、今回の改造版では文字列を返すメソッドにしたことで、このようにmainメソッドでは、単純にその戻り値の文字列を出力させるだけで済みます。
そのおかげで何回も連続して使いやすくなりました。こんなこともできます。
public class ReturnTest{ public static void main(String[] args){ System.out.println(isMultipleOf3(123456789)); System.out.println(isMultipleOf3(15)); System.out.println(isMultipleOf3(22)); System.out.println(isMultipleOf3(987654321)); } public static String isMultipleOf3(int n){ String resultMessage = ""; if(n % 3 == 0){ resultMessage = n + "は3で割り切れます"; }else{ resultMessage = n + "は3で割り切れません"; } return resultMessage; } }
これを実行すると、
こうなります。
というわけで、booleanを返すバージョンと、Stringを返すバージョンと作ってみました。
booleanを返すバージョンは、その戻り値を条件分岐に使えるので非常にいろんな使い方ができます。が、もし結果を文字列として表示する処理をmainメソッド内に書こうと思えば、mainメソッド自体がif文だらけになってしまいます。
一方、Stringを返すバージョンは戻り値は文字列なのでそれを出力するぐらいしか使い道はありません。しかし、上記の例のように続けて何回も出力しやすいというメリットもあります。
どちらが良いとか悪いとかではなく、自分で戻り値を返すメソッドを作る時には、何を戻り値として返せばそのメソッドを便利に使えるか?また、返ってきた値をどういう風に利用するか?をよく考えて作る必要があります。
まあこの辺は書いてみて、失敗して、修正して・・というのを繰り返すことで、だんだん分かってくると思うので、とにかく書いてみることだと思います。
戻り値と関数
メソッドは、「関数」と呼ばれることもあります。
関数というのは要は何かを入力したら何かが出力されるその法則のことです。函数とも書きます。函ってのはいわゆる箱です。箱に何かを入れると、何かが出て来るというイメージですね。
引数がいわゆる入力で、戻り値が出力と考えると、メソッドというのはまさに関数そのものです。
( )の中に入力値を入れると、メソッド自体が出力値に置き換わるわけです。
数学で扱う関数の場合は、入力も出力も数値のみですが、プログラミングの場合は数値以外のものも扱うことが可能です。
今回作ったisMultipleOf3メソッドのように、数値を入力した結果、文字列を出力する関数でも良いし、逆に文字列を入力して数値を出力する関数を作ることもできます。
慣れてくると自由自在です。関数を上手くつなげて組み上げていけば、少々複雑な処理でもシンプルなコードとして表現することができます。
こういった関数的な感覚が身につけば、コードを読むのも書くのも、格段にレベルアップします!
引数と戻り値は、メソッドをいわゆる関数として扱う為の重要な仕組みですのでしっかり理解しましょう。
※戻り値があろうと無かろうと、単にメソッドのことを関数と呼ぶ場合もあるので、メソッドと関数というのは明確に区別する必要はありません。
コンパイラによる型チェック
コンパイルエラーというのを経験したことはありますよね?
例えば、;(セミコロン)が抜けていたり、変数名のつづりが間違っていたりした時などになるアレです。誰もがやってしまうミスです。
コンパイルエラーというのは、プログラムを実行する前に一通りコンパイラがソースコードをチェックして、「このままプログラムを実行したらおかしなことになるよ!」というエラー箇所を見つけてくれているわけです。
戻り値は、実はコンパイラによる重要なチェック項目の1つです。
前回のisMultipleOf3メソッドは、戻り値としてbooleanを返しました。
どんな引数を渡されようとも、どんな場所で呼ばれようとも、isMultipleOf3メソッドが返すのは絶対にbooleanです。
isMultipleOf3メソッドが必ずbooleanを返すことが保証されているからこそ、if文の条件式としてこのメソッドを使うことが許されるんです。
if(isMultipleOf3(5)){ }
一方、今回書いたisMultipleOf3メソッドの戻り値はStringですので、もしif文の条件式にそのまま入れてしまうと、コンパイルエラーになります。
if(isMultipleOf3(5)){ } //コンパイルエラー
コンパイラはプログラムを実行するまでもなくすぐに気づきます。if文の条件式の中にStringが入っているようなソースコードは実行できない!って。isMultipleOf3メソッドが必ずStringを返すことは保証されているからです。
このようにJavaのコンパイラはプログラム実行前に、全てのメソッドについて戻り値の型を厳密にチェックすることで、ソースコードに辻褄の合わない箇所がないか見つけられるようになっています。
メソッドの定義時に戻り値の型(あるいはvoid)を書くのは、このメソッドは必ずbooleanを返しますよ!とかこのメソッドは何も戻り値を返しませんよ!と約束しているわけですね。
public static boolean methodA(int n){ }
↑戻り値は絶対にboolean型
public static int methodB(int n){ }
↑戻り値は絶対にint型
public static void methodC(int n){ }
↑戻り値は絶対に何も返さない
さて、メソッドについて一通り説明したところで、次回は、今まであまり深く考えずに使ってきたmainメソッドについて振り返ります。
今だけ→転職できなければ全額返金の「エンジニア転職保証コース」
絶対エンジニアになる!→テックエキスパート
フリーランスエンジニアの収入例を見てみる→レバテックフリーランス
コメント
String は文字列型の戻り値という事ですが、
int n の n は整数型ですよね?
resultMessageは文字型。
resultMessage = n + “は3で割り切れます”; で
resultMessage = 整数 + 文字列 としても、
コンパイルエラーにならずに実行できるのはなぜなのでしょう?
by 眠り王 2015/08/05 15:02
文字列と数値の足し算(連結)をご覧になって下さい。
by Nobuo@管理人 2015/08/05 15:45
初めてコメントさせていただきます。Androidでアプリを作りたくて色々調べてるうちにここにたどり着き、順番に勉強させていただいています。
説明の流れが分かりやすくて嬉しいです。
自分は、
→本文中の「~~というプログラムを作ってみましょう/改造してみましょう」というところまで読む
→とりあえず自分でやってみる
→コンパイルエラー等が出て、わからなくなったところで本文に戻る
みたいな利用の仕方をしているのですが、今回のisMultipleOf3メソッドで
public static String isMultipleOf3(int n){
if(n%3 == 0){
return n + “は3で割り切れます”;
}else{
return n + “は3で割りきれません”;
}
というように、String変数を使わずにやってしまいました。
コンパイルも実行もうまくいきましたが、見やすさの観点から言うとこの書き方はやめたほうがいいのでしょうか。
加えて、細かなことで恐縮なのですが、本文中の一枚目のスクリーンショットのあとにおいて、
> 一応、思った通りには動いているのですが、mainメソッドの中でif文でわざわざ分岐させているのが、非常にうっとうしいです。mainメソッドというのは極力すっきりさせておく方がプログラム的にはベターです。もっと戻り値の仕組みの理解を深める為にも、このclassを改造したいと思います。
これが元々のiaMultipleOf3メソッドの定義部分です。
この部分の最後の一行でメソッド名が微妙に間違ってる(sがaになってる?)気がします。
長々と失礼しました。
by 匿名希望 2016/07/27 11:59
>コンパイルも実行もうまくいきましたが、見やすさの観点から言うとこの書き方はやめたほうがいいのでしょうか。
自分で見にくくなければ問題はないと思います。ただ個人的にはif文の中でreturnするのは好きじゃないです。(^^;)
>この部分の最後の一行でメソッド名が微妙に間違ってる(sがaになってる?)気がします
ありがとうございます。細かい指摘は大歓迎です。
by Nobuo@管理人 2016/07/27 12:19
超初心者の疑問で申し訳ありません。
if文の前の「String resultMessage;」は「String resultMessage=””;」という風に初期化しなくてもよいのでしょうか?
初期化しなくてもエラーにはなりませんでしたが、「文字列を保持するString」の回で、if文の前で空の「””」を入れて初期化するとありましたが。
よろしくお願いします。
by 鶴亀 2017/02/13 15:59
>鶴亀さん
そうですね。した方がいいです。(^^;)
訂正しておきます。
ご指摘ありがとうございました。
by Nobuo@管理人 2017/02/15 15:46