Java/基礎/条件分岐

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

プログラムの流れをコントロールする、フロー制御構文には、反復処理と条件分岐の構文があります。(※ 条件分岐そのものの意味については『中学校技術/プログラムによる計測・制御』などを参照されたし。)

このページでは条件分岐について解説します。

条件分岐の例[編集]

if文[編集]

Wikipedia
ウィキペディアif文の記事があります。

Javaではif文を用いると、条件分岐をすることができます。(他の多くのプログラム言語でも同様、if文は条件分岐の命令です。)

次のサンプルは、Hello worldの“バイリンガル版”です。もちろん、Hello worldをバイリンガルにしても実用的な意義は全くありません。

さっそくサンプルを見てみましょう。

class trans {

  public static void main(String[] args) {
  
  String gengo;
  gengo = "ja";
  
    if (gengo == "en") {
      System.out.println("Hello, world.");
    } 
    
    if (gengo == "ja") {
      System.out.println("世界よこんにちは");
    } 
    
  }
}
実行結果
世界よこんにちは

もし、 gengo = "ja"; の引用符の中を「en」に変えて gengo = "en"; にすれば、

上記コードを実行すると英語で

Hello, world.

と表示する結果になります。

if文とはこのように、つづく条件の式を評価して、その条件が満たされている場合に、{ } ブロック内の処理を実行する命令のことです。

条件判定で用いる等号はイコール記号が2個である事に注意してください。もし条件式でイコール1個だけだと別の意味になり、バグやエラーになります。


仮引数[編集]

仮引数(かりひきすう)と言われる技法と、条件分岐を組み合わせると、コマンドラインからの入力に応じて、いろいろな処理を行うことが出来るようになります。

「仮引数」とは、コンパイルなどのコマンド入力時に、ファイル名の後ろに、

$ java trans -ja

さらに追加された文字列(上記の例なら「-ja」)は、「仮引数」として認識され、プログラム実行時にその文字列を利用することができます(この仕組み、あるいはこれによって渡された文字列などを、「仮引数」と言います)。

class trans {

  public static void main(String[] args) {

    if (args.length == 0) {

      System.out.println("Hello, world.");

    } else if (args[0].equals("-ja")) {

      System.out.println("世界よこんにちは");

    } else {

      System.err.println("Usage: java trans [-ja]");
    }
  }
}

上記は、if文if-else文と呼ばれる構文を使った例です。


コンパイル方法
$ javac trans.java
$ java trans

上記コマンドを実行すると、

Hello, world

と表示されます。

では日本語の「世界よこんにちは」は、どう表示するのでしょうか? コンパイル後に

$ java trans -ja

と引数に「-ja」をつけてコマンド実行すれば、

世界よこんにちは

のように表示されます。

switch文[編集]

基本[編集]

switch文というのは、場合わけに応じて、「case」で示したラベルにジャンプする命令です。

ジャンプしたあと、コードの実行を上から下に向かって実行していきます。

「case 1:」の最後の記号はコロン(:)です。セミコロン「;」とは間違えないようにしてください。

class sample {
  public static void main(String[] args) {

    int a = 2;

    switch (a) {
    
    case 1:
      System.out.println("第1パターンにいる.");
        
    case 2:
      System.out.println("第2パターンにいる.");

    case 3:
      System.out.println("第3パターンにいる.");

    };
  }
}
実行結果
第2パターンにいる.
第3パターンにいる.
解説

switch case文はその名に反して、単にラベルにジャンプするだけの命令なので、ジャンプ先にあるラベル(case 2)の次のラベル(case 3)の命令もそのまま実行しようとしてしまう。

switch文のこのような仕組みを、フォール・スルー(fall-through)という。


命令を場合ワケしたい場合はbreak;を使うと、switch文から抜け出すので、結果的に場合ワケした事と同じ結果になる。

class sample {
  public static void main(String[] args) {

    int a = 2;

    switch (a) {
    
    case 1:
      System.out.println("第1パターンにいる.");
      break;
        
    case 2:
      System.out.println("第2パターンにいる.");
      break;

    case 3:
      System.out.println("第3パターンにいる.");
      break;
    };
  }
}
実行結果
第2パターンにいる.


矢印記号->[編集]

switch文において、case の次をコロンではなくアロー(矢印)記号->にすると、breakがある場合と同じ結果になるので、コードを短縮できます。

つまり、アロー記号を使うことで、フォール・スルーを禁じたことになります。

Java SE 12以降で、アロー記号をこのような機能で使えます。

コード例
class sample {
  public static void main(String[] args) {

    int a = 2;

    switch (a) {
    
    case 1 ->  System.out.println("第1パターンにいる.");
        
    case 2 ->  System.out.println("第2パターンにいる.");

    case 3 ->  System.out.println("第3パターンにいる.");

    };
  }
}
実行結果
第2パターンにいる.


2行以上書きたい場合は、単に波カッコ{ }で、くくれば可能です。

class sample {
  public static void main(String[] args) {

    int a = 2;

    switch (a) {
    
    case 1 ->  System.out.println("第1パターンにいる.");
        
    case 2 -> { System.out.println("第2パターンにいる.");
                System.out.println("次.");

    case 3 ->  System.out.println("第3パターンにいる.");

    };
  }
}
実行結果
第2パターンにいる.
次.


歴史[編集]

switch文のコロンと矢印の新旧については、歴史的には、コロン「:」を使うジャンプ方式のほうが古く、標準C言語が古くからサポートしている方式もコロンによる方式です。

そもそも、アセンブラのジャンプ命令が、ほぼ同じ方式です。(というか、おそらくアセンブラのジャンプ命令を手本に、C言語の黎明期(れいめいき)にswitch文の仕様が制定されたのだろうと思われる。)

ですが、コロンによる方式は、上述のフォールスルーのように、場合分けの用途で用いるには紛らわしく(まぎらわしく)、欠点があります。

また、コロンの方式は、break文を毎回書く必要があったりと、コードに定型文を書く手間が増えます。もしコロン方式で、breakを書き忘れるミスをすると、バグにもなりかねます。このため、コロンの方式は、多くの用途では非効率です。

そこで今後はJavaプログラミングでは、(ジャンプ目的ではなく)場合分けの目的なら、なるべくアロー記号を使うほうが、バグなどのミスが減るし意図も明確になるので、なるべくアローを使うほうが望ましいでしょう。


switch式[編集]

Java SE 12以降の 比較的に新しい機能で、関数の戻り値のように、各caseから値を返す機能がある。

caseから値を返すにはyield を使う。

しかし、これ単独では使えず、下記のように列挙型を定義しないといけないように仕様が決まっている。

コード例
enum ctype {
  c1,
  c2,
  c3;
}

class sample {
  public static void main(String[] args) {

    ctype a = ctype.c2;
    int res = switch (a){

        case c1 -> {System.out.println("第1パターンにいる.");
                     yield 20;
                    }

        case c2 -> { System.out.println("第2パターンにいる.");
                    yield 33;
                   }

        case c3 -> { System.out.println("第3パターンにいる.");
                    yield 50;
                   }
    };

    System.out.println(res);
  }
}
実行結果
第2パターンにいる.
33


enum というのは、列挙型を宣言するためのキーワードです。