12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

条件分岐とreturnの基礎

Last updated at Posted at 2017-10-14

謎の条件分岐からの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;
	}
}

これは共通したルールですが、中途半端な言語特有のルール知識が絡まっていて整理できていなかったようです。

ということで、とりあえず納得いきましたが、ツッコミや+αなどありましたらコメント頂けると幸いです。

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?