JavaA2Z

KAB-studio > プログラミング > JavaA2Z > ラベルステートメントとは

ラベルステートメント

日本語 張り紙命令、付箋命令
英語 label statement
ふりがな らべるすてーとめんと
フリガナ ラベルステートメント

解説

break及びcontinueの「移動先」を指定するステートメント
ステートメントの一種。
 
ラベル:ステートメント」の形式で記述することができる。
ラベル:」の後の「ステートメント」(ブロックforステートメントwhileステートメント等)内で「break ラベル;」と記述することで、指定したステートメントの直後へと処理が移る。その際、中のブロックネストは無視される。
また同じく「continue ラベル;」と指定することで指定したステートメントの「次の周」へと処理を移すことができる。ただし、その際「ステートメント」にはforステートメント及びwhileステートメントの「ループ」をステートメントのみ使用できる。
 
ラベルを使用するということでgotoに似ているが、基本的に「ブロックの外」もしくは「次の周」にしか移動できないため、自由度は低く、その分安全である。
ただし、ラベルを使用しないbreakcontinueに比べて分かりにくく、ラベルそのものへの抵抗もあるためほとんど使用されることはない。
 
同じラベルだが、switch内のラベルとは別の分類であるため注意。

参考サイト

  • (参考サイトはありません)

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        // 「ラベル名:ステートメント」が「ラベルステートメント」
        // となります。たとえば「ブロック」ステートメントを使用する
        // 場合には以下のようになります。
        label_name:{}

        // breakでラベル名を指定することで、ラベル名の後の
        // ブロックのすぐ外へと移動することができます。
        label_out:
        {
            System.out.println( "外側ループ開始" );
            forint iF1 = 0; iF1 < 2; ++iF1 )
            {
                System.out.println( "内側ループ開始" );
                forint iF2 = 0; iF2 < 100; ++iF2 )
                {
                    System.out.println( iF1 + ", " + iF2 );
                    if    (
                        ( iF1 == 0 ) &&
                        ( iF2 == 2 ) 
                        )
                    {
                        // 普通のbreak。
                        break;
                    }

                    if    (
                        ( iF1 == 1 ) &&
                        ( iF2 == 2 ) 
                        )
                    {
                        // ラベルを指定したbreak。
                        break label_out;
                    }
                }
            }
        }
        System.out.println( "label_outのブロックの外。" );
        // 外側ループ開始
        // 内側ループ開始
        // 0, 0
        // 0, 1
        // 0, 2
        // 内側ループ開始
        // 1, 0
        // 1, 1
        // 1, 2
        // label_outのブロックの外。

        // このように、「break ラベル名;」という形で
        // 「ラベル名:{}」のすぐ後に移動します。


        // 「ラベル名:」の後ろにはステートメントであれば
        // なんでも記述できます。そのため、以下のように
        // forの前に記述することもできます。
        System.out.println( "外側ループ開始" );
        label_for: forint iF1 = 0; iF1 < 2; ++iF1 )
        {
            System.out.println( "内側ループ開始" );
            forint iF2 = 0; iF2 < 100; ++iF2 )
            {
                System.out.println( iF1 + ", " + iF2 );
                if    (
                    ( iF1 == 0 ) &&
                    ( iF2 == 2 ) 
                    )
                {
                    // ラベルを指定したbreak。
                    break label_for;
                }
            }
        }
        System.out.println( "外側のforループの外。" );
        // 外側ループ開始
        // 内側ループ開始
        // 0, 0
        // 0, 1
        // 0, 2
        // 外側のforループの外。

        // 「break ラベル名;」の指定をする場合、forやwhileとは
        // 関係なく移動できます。
        forint iF1 = 0; iF1 < 3; ++iF1 )
        {
            System.out.println( iF1 );
            System.out.println( "label_inの前" );
            label_in:
            {
                System.out.println( "label_inの最初" );
                if( iF1 == 1 )
                {
                    // iF1が1の時だけbreakします。
                    break label_in;
                }
                System.out.println( "label_inの最後" );
            }
            System.out.println( "label_inの後" );
        }
        // 0
        // label_inの前
        // label_inの最初
        // label_inの最後
        // label_inの後
        // 1
        // label_inの前
        // label_inの最初
        // label_inの後
        // 2
        // label_inの前
        // label_inの最初
        // label_inの最後
        // label_inの後

        // iF1が1の時だけ「label_inの最後」がありません。
        // label_inで指定したラベルの後のブロックの直後に
        // 移動しているからです。

        // forやwhileの中じゃなくてもbreak可能です。
        System.out.println( "label_normalblockの前" );
        label_normalblock:
        {
            System.out.println( "label_normalblockの最初" );
            break label_normalblock;
            // System.out.println( "label_normalblockの最後" );
            // コンパイルエラー:
            // 到達不能コード
        }
        System.out.println( "label_normalblockの後" );
        // label_normalblockの前
        // label_normalblockの最初
        // label_normalblockの後

        // ネストが異なれば同じ名前のラベルがあっても問題ありません。
        label_AAA:{}
        label_AAA:{}

        // ネスト外のラベルにbreakすることはできません。
        label_other:{}
        // break label_other;
        // コンパイルエラー:
        // 欠落ラベル label_other

        // 同じ名前のラベルがネスト内に2つ以上あるとコンパイルエラーです。
        label_samename:
        {
            // label_samename:{}
            // コンパイルエラー:
            // 重複ラベル label_samename
        }

        // ラベルの後には、ブロックに限らずステートメントを
        // 記述することができます。
        // ですので、以下のように代入や式、空ステートメントも記述できます。
        // ただ、当然そのステートメントの中でbreakやcontinueが
        // 使用できないと意味がありません。
        int i;
        label_assignment: i = 100;
        label_expression: i = i + 200;
        label_empty:;

        // continueでラベル名を指定することで、指定したforループや
        // whileループの「次の周」へと移ることができます。
        label_out:
        {
            System.out.println( "外側ループ開始" ); 
            label_for: forint iF1 = 0; iF1 < 3; ++iF1 )
            {
                label_mid:
                {
                    System.out.println( "内側ループ開始" ); 
                    forint iF2 = 0; iF2 < 4; ++iF2 )
                    {
                        label_in:
                        {
                            System.out.println( iF1 + ", " + iF2 ); 
                            if    (
                                ( iF1 == 0 ) &&
                                ( iF2 == 2 ) 
                                )
                            {
                                // 普通のcontinue。
                                continue;
                            }

                            if    (
                                ( iF1 == 1 ) &&
                                ( iF2 == 2 ) 
                                )
                            {
                                // ラベルを指定したcontinue。外側のforの
                                // iF2が2の周がスタートします。
                                continue label_for;
                            }

                            // forやwhileといった、ループと関係のあるステートメント
                            // の前にないラベルは指定できません。
                            
                            // continue label_out;
                            // コンパイルエラー:
                            // ループ継続ポイントがありません。

                            // continue label_mid;
                            // コンパイルエラー:
                            // ループ継続ポイントがありません。

                            // continue label_in;
                            // コンパイルエラー:
                            // ループ継続ポイントがありません。
                        }
                    }
                }
            }
        }
        // 外側ループ開始
        // 内側ループ開始
        // 0, 0
        // 0, 1
        // 0, 2
        // 0, 3
        // 内側ループ開始
        // 1, 0
        // 1, 1
        // 1, 2
        // 内側ループ開始
        // 2, 0
        // 2, 1
        // 2, 2
        // 2, 3

        // iF1が1の時の周でlabel_forにcontinueで飛んでいます。
        // 中のforから見るとbreakみたいに見えます。
    }
}
// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        // 「ラベル名:ステートメント」が「ラベルステートメント」
        // となります。たとえば「ブロック」ステートメントを使用する
        // 場合には以下のようになります。
        label_name:{}

        // breakでラベル名を指定することで、ラベル名の後の
        // ブロックのすぐ外へと移動することができます。
        label_out:
        {
            System.out.println( "外側ループ開始" );
            for( int iF1 = 0; iF1 < 2; ++iF1 )
            {
                System.out.println( "内側ループ開始" );
                for( int iF2 = 0; iF2 < 100; ++iF2 )
                {
                    System.out.println( iF1 + ", " + iF2 );
                    if    (
                        ( iF1 == 0 ) &&
                        ( iF2 == 2 ) 
                        )
                    {
                        // 普通のbreak。
                        break;
                    }

                    if    (
                        ( iF1 == 1 ) &&
                        ( iF2 == 2 ) 
                        )
                    {
                        // ラベルを指定したbreak。
                        break label_out;
                    }
                }
            }
        }
        System.out.println( "label_outのブロックの外。" );
        // 外側ループ開始
        // 内側ループ開始
        // 0, 0
        // 0, 1
        // 0, 2
        // 内側ループ開始
        // 1, 0
        // 1, 1
        // 1, 2
        // label_outのブロックの外。

        // このように、「break ラベル名;」という形で
        // 「ラベル名:{}」のすぐ後に移動します。


        // 「ラベル名:」の後ろにはステートメントであれば
        // なんでも記述できます。そのため、以下のように
        // forの前に記述することもできます。
        System.out.println( "外側ループ開始" );
        label_for: for( int iF1 = 0; iF1 < 2; ++iF1 )
        {
            System.out.println( "内側ループ開始" );
            for( int iF2 = 0; iF2 < 100; ++iF2 )
            {
                System.out.println( iF1 + ", " + iF2 );
                if    (
                    ( iF1 == 0 ) &&
                    ( iF2 == 2 ) 
                    )
                {
                    // ラベルを指定したbreak。
                    break label_for;
                }
            }
        }
        System.out.println( "外側のforループの外。" );
        // 外側ループ開始
        // 内側ループ開始
        // 0, 0
        // 0, 1
        // 0, 2
        // 外側のforループの外。

        // 「break ラベル名;」の指定をする場合、forやwhileとは
        // 関係なく移動できます。
        for( int iF1 = 0; iF1 < 3; ++iF1 )
        {
            System.out.println( iF1 );
            System.out.println( "label_inの前" );
            label_in:
            {
                System.out.println( "label_inの最初" );
                if( iF1 == 1 )
                {
                    // iF1が1の時だけbreakします。
                    break label_in;
                }
                System.out.println( "label_inの最後" );
            }
            System.out.println( "label_inの後" );
        }
        // 0
        // label_inの前
        // label_inの最初
        // label_inの最後
        // label_inの後
        // 1
        // label_inの前
        // label_inの最初
        // label_inの後
        // 2
        // label_inの前
        // label_inの最初
        // label_inの最後
        // label_inの後

        // iF1が1の時だけ「label_inの最後」がありません。
        // label_inで指定したラベルの後のブロックの直後に
        // 移動しているからです。

        // forやwhileの中じゃなくてもbreak可能です。
        System.out.println( "label_normalblockの前" );
        label_normalblock:
        {
            System.out.println( "label_normalblockの最初" );
            break label_normalblock;
            // System.out.println( "label_normalblockの最後" );
            // コンパイルエラー:
            // 到達不能コード
        }
        System.out.println( "label_normalblockの後" );
        // label_normalblockの前
        // label_normalblockの最初
        // label_normalblockの後

        // ネストが異なれば同じ名前のラベルがあっても問題ありません。
        label_AAA:{}
        label_AAA:{}

        // ネスト外のラベルにbreakすることはできません。
        label_other:{}
        // break label_other;
        // コンパイルエラー:
        // 欠落ラベル label_other

        // 同じ名前のラベルがネスト内に2つ以上あるとコンパイルエラーです。
        label_samename:
        {
            // label_samename:{}
            // コンパイルエラー:
            // 重複ラベル label_samename
        }

        // ラベルの後には、ブロックに限らずステートメントを
        // 記述することができます。
        // ですので、以下のように代入や式、空ステートメントも記述できます。
        // ただ、当然そのステートメントの中でbreakやcontinueが
        // 使用できないと意味がありません。
        int i;
        label_assignment: i = 100;
        label_expression: i = i + 200;
        label_empty:;

        // continueでラベル名を指定することで、指定したforループや
        // whileループの「次の周」へと移ることができます。
        label_out:
        {
            System.out.println( "外側ループ開始" ); 
            label_for: for( int iF1 = 0; iF1 < 3; ++iF1 )
            {
                label_mid:
                {
                    System.out.println( "内側ループ開始" ); 
                    for( int iF2 = 0; iF2 < 4; ++iF2 )
                    {
                        label_in:
                        {
                            System.out.println( iF1 + ", " + iF2 ); 
                            if    (
                                ( iF1 == 0 ) &&
                                ( iF2 == 2 ) 
                                )
                            {
                                // 普通のcontinue。
                                continue;
                            }

                            if    (
                                ( iF1 == 1 ) &&
                                ( iF2 == 2 ) 
                                )
                            {
                                // ラベルを指定したcontinue。外側のforの
                                // iF2が2の周がスタートします。
                                continue label_for;
                            }

                            // forやwhileといった、ループと関係のあるステートメント
                            // の前にないラベルは指定できません。
                            
                            // continue label_out;
                            // コンパイルエラー:
                            // ループ継続ポイントがありません。

                            // continue label_mid;
                            // コンパイルエラー:
                            // ループ継続ポイントがありません。

                            // continue label_in;
                            // コンパイルエラー:
                            // ループ継続ポイントがありません。
                        }
                    }
                }
            }
        }
        // 外側ループ開始
        // 内側ループ開始
        // 0, 0
        // 0, 1
        // 0, 2
        // 0, 3
        // 内側ループ開始
        // 1, 0
        // 1, 1
        // 1, 2
        // 内側ループ開始
        // 2, 0
        // 2, 1
        // 2, 2
        // 2, 3

        // iF1が1の時の周でlabel_forにcontinueで飛んでいます。
        // 中のforから見るとbreakみたいに見えます。
    }
}

この単語を含むページ

「みだし」に含まれているページ

「解説」に含まれているページ

「サンプルプログラムとか」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2006/02/18
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。