謎の条件分岐からのreturnをしないとエラーになるので悩んだ件
if文のあるコードを書いていて、「returnがないよ!!」と、Eclipseに怒られることが何度かありました。
しかし、なぜなのかわからず。。。
より原始的な形で考えようということで、int型の引数を二つ渡すと、大きい方を返すメソッドを書いてみました(max関数を使えば一発なのですが、わかりやすい例で実験したかったので)。
//コード1
public class BiggerNumber {
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
System.out.println(returnBiggerNumber(250,500));
}
public static int returnBiggerNumber(int num1,int num2) {
if (num1 < num2) {
return num2;
}else if (num1> num2 ) {
return num1;
}else if (num1 == num2) {
return num1;
}else { //←コレ!
return num1;
}
}
}
理解不能だったのは、最後のelseです。これを書かないとコンパイルエラーになる。。。
この極めて単純なメソッドの場合、分岐の可能性は3つしかありません。
1. num1の方が大きい
2. num2の方が大きい
3. num1とnum2はイコール
理論的にはこれで可能性は網羅しているはず。。。
どんな数字が引数に来てもreturnできるはずなのに、
これ以外の可能性ってあるのか?と悩んでいました。
原因と、それを踏まえた書き方
エラー原因をjava歴の長い先輩に聞いたところ、
『コンパイラーは全ての条件分岐がもれなく書かれているか否か、判断することはできない。
そのため、実際には到達することがありえない条件分岐であっても、形式的に書いておく必要がある。』
とのことでした。
「なるほど!」
であれば、<、>以外の分岐可能性は==しかないのだから、
==の条件式をわざわざ書く必要はないとも考えられます。
そこで(私が)まず思いつくのはこれ。
//コード2
public static int returnBiggerNumber(int num1,int num2) {
if (num1 < num2) {
return num2;
}else if (num1> num2 ) {
return num1;
}else {
return num1;
}
}
あるいはこれもあり。
//コード3
public static int returnBiggerNumber(int num1,int num2) {
if (num1 < num2) {
return num2;
}else if (num1> num2 ) {
return num1;
}
return num1;
}
少し違和感がありますが、これも有効。このあたりは好みの問題なのでしょうか。
//コード4
public static int returnBiggerNumber(int num1,int num2) {
if (num1 < num2) {
return num2;
}else if (num1> num2 ) {
return num1;
}else if (num1 == num2) {
}
return num1;
}
Swiftのswitch{case}と混同(半分個人的なメモとして)
そもそも、全てのパターンに対してreturnできているのだから問題ないはず!と自分が思い込んでいたのは、Swiftのswitch文のルールが原因でした。
それがこれ。
『switchに与えられた値の型が取りうる全ての値をカバーするcase節が存在するか、
default節が存在する必要がある。』
(※因みにJavaではその必要はないし、同じSwiftでもif文ではその必要なし)
いやいや、**これ戻り値関係ない話だし。。。**勘違いしていました。
Javaのswitch文にせよ、swiftのif文にせよswitch文にせよ、
戻り値を返す関数・メソッドならば、どんな値がきても全て打ち返す(returnする)必要はあります。
一応念のため、例えば
public int returnTest(int i) {
switch (i) {
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
//このようにdefault、もしくはswitchブロックの外に必ずreturnを書かなければならない。
//なお、swiftではこの書き方はエラーになるので、switchブロックの外に書く。
default:
return 4;
}
}
これは共通したルールですが、中途半端な言語特有のルール知識が絡まっていて整理できていなかったようです。
ということで、とりあえず納得いきましたが、ツッコミや+αなどありましたらコメント頂けると幸いです。