制御構造: 分岐 if、switch

制御構造: 一般的な分岐処理 if

条件が成り立つ・成り立たないで実行を分岐

C言語での用法と同じ。

パターン1:   if ( 条件 ) 〜

条件が成り立つときだけ〜を実行

パターン2:   if ( 条件 ) 〜 else …

条件が成り立つとき〜を実行、成り立たないとき…を実行

パターン3:   if 〜 else if 〜 else if 〜 else if 〜 else … による多岐分岐

条件を上から順に調べていき、最初に条件が成り立つif文の本体を実行する。
全部の条件が成り立たない場合は、最後に else があれば、else 以降の処理を実行する。
全部の条件が成り立たず、最後に else もない場合は何も実行しない。


演習3 : if文による単発数当て

以下のようなアプリケーション (クラス名 Ex3、ファイル名 Ex3.java) を作りなさい。

クラスのmain メソッドの中で、以下のようなコードで、1〜99 までの範囲の整数 r を決める。

java.util.Random rand = new java.util.Random();
int r = rand.nextInt(99) + 1;

クラス java.util.Random は、擬似乱数を求めるためのクラスで、メソッド public int nextInt(int n) は 0 以上 (n-1) 以下の範囲の一様分布の擬似乱数を返す。
上のコードでは rand.nextInt(99) 呼び出しで 0 以上 (99-1) 以下のint型整数の擬似乱数が返り、それに1を加えているので、変数 r は 1 以上 99 以下の整数の擬似乱数の値となる。

※※※※※
上のコードは import を使わない場合の書き方。ソースの先頭で
import java.util.Random;
のように、java.util.Random を import すれば、上の一行目のコードを
Random rand = new Random();
と、短く記述することができる。
この場合、java.util.Random をクラスの完全修飾名、単なる Random をクラスの単純名という。詳しくは パッケージとクラスの完全修飾名 を参照すること。
※※※※※

次に、キーボードから一つの整数を入力する。

まず、入力値が 1 〜 99 の範囲になければ、適切なエラーメッセージを表示し終了する。

次に、r の値が

と表示する。(… の部分は、整数 r の実際の値が入る)

コンパイル・実行し、下記入力をしてみなさい。

プログラムのソースファイルおよび上記入力のときのプログラム出力 (数値入力部分も含む) をテキストファイル (拡張子 txt) にまとめる。

多く見られる間違い

解答例


制御構造: 多岐分岐 switch 〜 case 〜 default 〜

long 以外の整数式 (int, short, byte, char のどれか) ※ の値に応じて多岐分岐する。

C言語と同じ使い方ができる。一部機能が拡張されている。

switch ( long以外の整数式 ※ ) {

     case 値1:
        処理1;
        break;

     case 値2:
        処理2;
        break;

     case 値n:
        処理n;
        break;

     default:    // 該当するcase値がないときの処理
         // (defaultがなければ、該当するcase値がないときはswitch文の中で何も処理されない)
        処理x;
        break;

}

breakをつけないと続けて下の処理も実行してしまう (フォールスルー (fall through) と言う)ので注意。

※ Java 5 以降では enum 型のオブジェクトも使用できる。
さらに Java 7 以降では、String オブジェクトによって多岐分岐が可能になった。
ただし、null を switch の丸括弧の中の式に渡すと NullPointerException 例外が発生するので注意する必要がある。
※※ Java 21 以降では、case null: で null 値を場合分けできる。case null, default: として、null 値とデフォルトの処理を合わせることもできる。

Java 21 以降では、レコードおよびシールクラスでも場合分けできるようになった。


caseラベルでは、Java 14より前では

case 値:

の形で、単一の値に対してのみ場合分けできた。
Java 14以降では、

case 値1, 値2, 値3:

のような形で、caseラベルにコンマ区切りで複数の値を並べて指定して場合分けできるようになった。


演習4 : 年齢による多岐分岐処理

以下のようなアプリケーション (クラス名 Ex4、ファイル名 Ex4.java) を作りなさい。

キーボードから、整数変数 age の値を入力する。
まず、if文によるチェックで、age の値がマイナスおよび 150 以上なら、それぞれの場合として適切なエラーメッセージを表示し終了する。
次に、switch文により、(age/5) の値が

するアプリケーションを作りなさい。defaultラベルも使用すること。

コンパイル・実行し、下記入力をしてみなさい。

  1. 入力値を自分の現在の年齢としたとき
  2. 入力値を 各自の学籍番号の最後の2桁 としたとき。ただし、1の入力と同じ値になる人は「100 - 最後の2桁」としたとき。
    学籍番号が 25CWXYZ のとき、入力値は YZ となる。(1の入力と同じ値になる人は 100 - YZ)

プログラムのソースファイルおよび入力1, 2のときのプログラム出力 (数値入力部分も含む) をテキストファイル (拡張子 txt) にまとめる。

多く見られる間違い

解答例


switch のアロー構文と switch式 (Java 14 以降)

上で説明している switch 文の構文では

case 値:

の形のcaseラベルで場合分けした処理を実行できるが、break を忘れてフォールスルーする危険性がある。
Java 14で導入されたswitchのアロー構文は、

case 値 -> 式または文;

default -> 式または文;

のように、コロンの代わりにアロー  -> を使う記述法で、下記の様に、1つのcaseに複数の値をコンマ区切りで入れて、複数の値に対応させることもできる。

case 値1, 値2, 値3 -> 式または文;

一つのswitchの中に従来のcaseラベルとアロー構文を混在させることはできない。
アロー構文でswitchを記述している場合、従来の記述法より簡潔に書けることも利点だが、フォールスルーをしないので安全性が高いと言える。

また、従来は switch 全体は文であり、値を持たなかった。Java 14 以降では、値を持つ形の switch式 を使って、switch全体の結果を演算に使ったり変数に入れたりメソッドのパラメータに入れたりできるようになった。

注意点として、switch式の場合、switchの丸括弧の中で評価する式が取り得るすべての値を網羅した場合分けをする必要がある。この網羅性の制約により、switchの丸括弧の中に整数式を与える場合は、実質上、default が必須となる。

switch のアロー構文と switch式を使って、演習4 の中心部分を書き直してみると例えば下記のようになる。

    String msg = switch (age/5) {
        case 0 -> "幼年期";
        case 1, 2 -> "少年期";
        case 3, 4 -> "青年期";
        case 5, 6, 7, 8 -> "壮年期";
        case 9, 10, 11, 12 -> "中年期";
        default -> "高年期";
    } + "です";
    System.out.println(msg);

従来記法の演習4のコードに比べて、非常にすっきりと簡潔に書けていることが分かる。なお、上ではswitch式の値 (上例ではString型) を "です" と結合してから一旦String型の変数に代入しているが、下記の様に、変数に代入しない、より直接的な書き方もできる。

    System.out.println(switch (age/5) {
        case 0 -> "幼年期";
        case 1, 2 -> "少年期";
        case 3, 4 -> "青年期";
        case 5, 6, 7, 8 -> "壮年期";
        case 9, 10, 11, 12 -> "中年期";
        default -> "高年期";
    } + "です");