Javaにgotoステートメントはありますか?


259

私はこれについて混乱しています。私たちのほとんどは、Javaにはgotoステートメントがないと言われています。

しかし、Javaのキーワードの1つであることがわかりました。どこで使用できますか?使えないのに、なぜJavaにキーワードとして含まれていたのか?


13
アドバイスのみ:gotoを使用しないでください
lostiniceland 09

16
そして、「「有害と考えられるステートメントに行く」「有害と考えられる」と「有害と考えられるステートメントに行く」「有害と考えられる」がある。VEEEEERY再帰、このミーム。
Chris Charabaruk、2009

70
「goto」は常に邪悪です-「goto work」や「goto school」のように;)
Andreas Dolk

24
本当の理由は、「g ** o」という言葉がほとんどのプログラミング言語でわいせつと見なされていることです。Javaデザイナは、罪のない若いプログラマを、影響の破損から保護しています。(:
スティーブンC

25
gotoに対する魔女狩りは、私の人生で最も深刻な瞬間のいくつかを生み出しました。私は、関数の機能を非表示にしてCコードを歪めたり、ばかげた終了ロジックを複数のネストされたループに入れたり、その他の方法で想像以上の過剰なエンジニアリングを行って、コードレビューでコードを批判されないようにしています。このルールは、「複数のリターンを避けなければならない」というカナードとともに、無意味に染み込んでいます。gotoによって物事の保守性が低下する場合があります。gotoによって物事がより保守しやすくなる場合があります。私はこの魔女狩りが80年代に死ぬことを望んでいました。

回答:


200

Javaのキーワードのリストは、指定しgotoたキーワードを、それは「使用しない」とマークされています。

元のJVMにありましたが(@VitaliiFedorenkoの回答を参照)、削除されました。これは、Javaの新しいバージョンに追加される場合に備えて、予約済みキーワードとして保持された可能性があります。

gotoリストになかった場合、後で言語に追加されると、その単語gotoを識別子(変数名、メソッド名など)として使用した既存のコードは機能しなくなります。しかし、gotoはキーワードであるため、そのようなコードは現在でもコンパイルされず、既存のコードを壊すことなく、後で実際に何かを実行させることが可能です。


29
This was probably done in case it were to be added to a later version of Java.実際、主な理由は少し異なります(以下の私の回答を参照)
Vitalii Fedorenko 2010

2
これは良い興味深い情報ですが、なぜそれがまだ予約キーワードであるのかについては説明していません。
Thomas

@トーマスそれが予約されている理由をあなたは説明しませんでしたか?これはキーワードなので、現在は使用できません。後でgotoを実行すると、問題が発生することなく元の状態に戻ります。予約語でなかった場合は、gotoが導入された場合に機能しなくなるコード(int goto = 2;)を生成するために使用できます。

230

James Goslingは、gotoステートメントのサポートを備えた元のJVMを作成しましたが、この機能を不要として削除しました。主な理由gotoは不要です。通常、より読みやすいステートメント(などbreak/continue)に置き換えるか、コードをメソッドに抽出することで置き換えることができるためです。

出典:James Gosling、Q&Aセッション


24
「...またはメソッドにコードの一部を抽出することによって」-適切な末尾呼び出しの排除なしでは非常にクールでなければなりません。
表示名

45
時には、の賢明な使用がgoto あるので、何か他のものにそれを強制的にPERFORCEのある、何かを表現するための最もreadybleと明確な方法読みにくく
Deduplicator 2014年

1
@Deduplicator gotoの使用は、賢明な場合もあるが、常にエラーが発生しやすい。
チェレビミュラ

@Deduplicator C ++でのgotoの使用が良いと見なされているのは、break / continueだけです。

2
Gotoは、Javaの予約キーワードであるため、ラベルに「goto:」という名前を付けることができません。

147

キーワードは存在しますが、実装されていません。

gotoを使用するのに私が考えることができる唯一の良い理由はこれです:

for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        goto outsideloops; // to break out of both loops
    }
}
outsideloops:

Javaではこれを次のように行うことができます:

loops:
for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        break loops;
    }
}

1
@Zoltánいいえ-最初のループの直前にコードをラベルにリダイレクトします。
アッシリア2012年

21
@assyliasまあ、そうではありません。ラベルは外側のループにラベルを付けます。次にbreak loops、「というループから抜け出す」という意味loopsです。振り返ってみると、ラベルのより良い名前があったかもしれませんouter
jonnystoten

8
「gotoを使用する唯一の正当な理由」無条件の無限ループを必要とする速くて汚い小さなプログラムは、gotoをうまく利用しています。while (true) {...の使用}はやり過ぎです。GOTOは不適切な使用のために非難されることがよくありますが、ブールリテラルとの不要な比較はGOTOよりも悪いと私は主張します。
アレクサンダー-モニカ

1
ループのラベルはループの後に置くべきではありませんか?
GC_

1
私は最近、このラベル付け手法がcontinue LABEL;ステートメントと組み合わせて非常に役立つことも発見しました。したがって、外側にあるループを続けることができます。
infotoni91 2018年

43

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html

「キーワードconstおよびgotoは、現在使用されていなくても予約されています。」


12
「無署名」はそこにもありません!(ため息)
Matthieu 2015

Javaのすべてのプリミティブ型が署名されているため、理にかなっています。
mwieczorek 2018年

1
@mwieczorekすべてではありません。「char」はプリミティブ型であり、符号なしです。
Sergey Krivenkov

29

したがって、言語設計者が必要性を感じた場合、それらはいつか使用できます。

また、これらのキーワードを持つ言語(C、C ++など)のプログラマーが誤ってそれらを使用した場合、Javaコンパイラーは有用なエラーメッセージを表示できます。

または多分それはただgotoを使用しているプログラマーを停止することでした:)


Javaに欠けているgoto機能は、gotoを使用しない理由として十分なはずです。キーワードとして予約する必要はありません。ロジックに従うと、他の言語で使用されるか、Javaデザイナーが将来使用する可能性があるため、すべてがキーワードになります...
stuXnet

1
私の論理がすべてがキーワードであることを暗示するとは思いません。多くのプログラミング言語で使用されている少数のキーワードがあり、Javaで検出して処理することができます。Java はC / C ++の遺産を予約しgotoconst反映していますが、実装されていないままです(後者の実装については議論があります)。カップルより多くのようにassertしてenum最初に予約されていなかったが、おそらくされている必要があり、彼らは実装されている与えられました。しかし、後知恵は素晴らしいことです。
デイブ2014

19

それらは将来の使用のために予約されています(Java言語のキーワードを参照)

キーワードconstおよびgotoは、現在使用されていなくても予約されています。

理由はなぜ何のgoto文はJavaではありませんが「で見つけることができますJava言語環境」:

Javaにはgotoステートメントがありません。研究は、gotoが単に「そこにあるから」というよりも(誤って)使用されることを示しています。gotoを削除すると、言語が単純化されます。たとえば、forステートメントの途中にgotoが及ぼす影響についての規則はありません。約100,000行のCコードに関する調査では、ネストされたループから抜け出す効果を得るために、gotoステートメントの約90%が純粋に使用されていることがわかりました。上記のように、マルチレベルのブレークアンドコンティニューにより、gotoステートメントの必要性のほとんどが取り除かれます。


goto予約されていますが、将来の使用のためではありません。
ローンの侯爵

17

Javaで「継続」ラベルを使用する方法の例は次のとおりです。

public class Label {
    public static void main(String[] args) {
        int temp = 0;
        out: // label
        for (int i = 0; i < 3; ++i) {
            System.out.println("I am here");
            for (int j = 0; j < 20; ++j) {
                if(temp==0) {
                    System.out.println("j: " + j);
                    if (j == 1) {
                        temp = j;
                        continue out; // goto label "out"
                    }
                }
            }
        }
        System.out.println("temp = " + temp);
    }
}

結果:

I am here // i=0
j: 0
j: 1
I am here // i=1
I am here // i=2
temp = 1

10

gotoプログラマーがマシンコードとアセンブリ言語でプログラミングした時代の構造が残っていることを理解することが重要です。これらの言語は非常に基本的であるため(各命令は1つの処理しか行わないなど)、プログラム制御フローはgotoステートメントで完全に実行されます(ただし、アセンブリ言語では、これらはジャンプまたは分岐命令と呼ばれます)。

現在、C言語はかなり低レベルですが、非常に高レベルのアセンブリ言語と考えることができます。Cの各ステートメントと関数は、簡単にアセンブリ言語の命令に分解できます。Cは今日のコンピューターをプログラミングするための主要言語ではありませんが、組み込みシステムなどの低レベルのアプリケーションでは依然として頻繁に使用されています。Cの関数はアセンブリ言語の関数を非常によく反映しているため、Cにgoto含まれていることだけが理にかなっています。

JavaがC / C ++の進化形であることは明らかです。JavaはCの多くの機能を共有していますが、より多くの詳細を抽象化しているため、単純に異なる方法で書かれています。Javaは非常に高水準の言語であるためgoto、関数、for、for each、whileループなどのより高水準の構造がプログラム制御フローを行う場合のように、低水準の機能を用意する必要はありません。あなたが1つの関数にいgotoて、ラベルに対して別の関数にしたと想像してみてください。他の関数が戻るとどうなりますか?この考えはばかげています。

これは必ずしもJavaにgotoステートメントが含まれているにもかかわらずコンパイルできない理由に必ずしも答えるものではありませんが、なぜgoto最初から下位レベルのアプリケーションで使用されたのか、なぜそれが意味をなさないのかを知ることが重要ですJavaで使用されます。


「プログラム制御フローはgotoで完全に行われます」。まあ、無条件の後藤とは限りません。
Peter Mortensen

C / C ++では、ある関数から別の関数のラベルに「goto」でジャンプすることもできません。C / C ++のGotoは、単一の関数ブロックに制限されています。
user2328447 2017年

「より高レベルの構成要素の場合、gotoのような低レベルの機能は必要ありません」-「必要性と十分性」を覚えておいてください。それは単に「必要ない」だけです。したがって、理由はありません。理由は何ですか:「実行可能コード」にジャンプしたいがJavaがバイトコードであるため「実行可能」ではない場合、アセンブラーのJMP、BNEなどの「高レベル」代替としての「Goto」は妥当です。;-)
reichhart

10

いいえ、goto使用されませんが、ラベルを定義してループまでラベルを残すことができます。ラベルを使用するbreakか、continue続けて使用できます。したがって、複数のループレベルからジャンプすることができます。見ていチュートリアルを


9

いいえ、ありがたいことに、gotoJava にはありません。

gotoキーワードは予約済みますが、(同じのために行く使用されませんconst)。


ここで予約が何を意味するのかわかりますか?コードでgotoとconstを使用するのが良い習慣ではない場合、なぜそれを予約するのですか?説明していただけますか?
Gopi

@Sri Kumar:@applechewerの回答を参照してください。存在しますが、実装されていません。
Valentin Rocher、2010年

1
@Sri Kumar:予約済みキーワードは、変数名などとして使用することを禁止します。このようにして、これらのキーワードは、Javaの将来のバージョンで実装することができます。
Peter Di Cecco

8

それはサポートされgotoていないので、何もしないキーワードや名前の変数が必要なのはなぜgotoですか?

break label;and continue label;ステートメントを使用して、効果的に何をすることもできますgotoが。しかし、私はそれをお勧めしません。

public static void main(String [] args) {

     boolean t = true;

     first: {
        second: {
           third: {
               System.out.println("Before the break");

               if (t) {
                  break second;
               }

               System.out.println("Not executed");
           }

           System.out.println("Not executed - end of second block");
        }

        System.out.println("End of third block");
     }
}

10
-1 gotoという名前の変数またはメソッドを持つことを許可されないのはなぜですか?
マイケルボルグワート

4
それは、Javaには当てはまらないプログラミングの世界で意味があるからです。また、変数名の選択としても不適切です。
pjp 2009

変数「印刷」は何に使用されますか?あなたが言及した単語は、変数やキーワードというよりもメソッド名に似ています。
pjp 2009

3
-1:まず、Javaが "goto"フロー制御ステートメントをサポートしていないからといって、それが何もしない "goto"キーワードがある理由ではありません。次に、「goto」は不適切な変数名かもしれませんが、「goto」がキーワードであるため、使用できない優れたメソッド名になる可能性があります。第3に、「ブレークラベル」と「コンティニューラベル」は非常に正当な理由で存在するため、「非推奨」はあまり役に立ちません。そして、第4に、Sunは「現在は使用されていません」と言っているため、以前は実装を計画していたが、別の方法で決定したときにキーワードを削除したくないことを意味します。
Vojislav Stojkovic

2
@VojislavStojkovicそれはただおかしな話です。1)それ何もしない理由は、サポートしていないからです。JLSによると、The keywords const and goto are reserved, even though they are not currently used. This may allow a Java compiler to produce better error messages if these C++ keywords incorrectly appear in programs.これは「使用しないので、C ++のバックグラウンドを使用している場合は、まったく使用させない」という意味です。2)gotoはひどいメソッド名です。ごめんなさい。3)中断して続行することをお勧めしますが、ここでは使用しません。4)「最も可能性が高い」[引用が必要]。
corsiKa 2014年

7

いいえ、goto予約語ですが、Javaでは使用されていません。同じことがにも当てはまりますconst。これらは両方ともC ++で使用されているため、おそらく予約されています。意図はおそらく、Javaに移行するC ++プログラマーを混乱させないようにすることと、Javaの今後のリビジョンでそれらを使用するオプションを維持することでした。


1
私は本当にgoto近い将来サポートされないことを本当に望んでいます;)
Bozho

6
@Bozho:まあ、それは悪い古い「有害な」gotoとはまったく関係のないいくつかの独創的な新機能に使用できます。
マイケルボルグワート

3

gotoの無害な使用のほとんどを次のように置き換えることができることに注意してください。

  • 帰る

  • ブレーク

  • ラベルを破る

  • try-catch-finallyの中に投げ込む


5
フロー制御には例外を使用しないでください
-ChssPly76

13
例外フロー制御に使用されます、例外的な場合にのみ使用してください。たとえば、Cでのgotoの使用の1つは、特にクリーンアップが含まれる場合のエラー処理です。
スターブルー2009

2
@starblue、あなたは私の口から言葉を取り出しました。例外のスロー制御フローです。実際、Cでは、最初にsetjmpを処理コードに確実に設定し、それに例外時にlongjmp()を実行することで、setjmp / longjmpを介して例外処理をいくぶんきれいに実装できます。

ifチェックを実行し、trueの場合はメソッドの半分をスキップします。行くことなく私は他の巨人を使わなければなりません。IMOは、あまりにも多くの
括弧

1
@WVrockあなたが試すことができますreturn
Andrew Lazarus

2

指摘されたように、gotoJava にはありませんが、ある日SunがgotoJavaに追加したいと思った場合に備えて、キーワードは予約されていました。彼らは多くのコードを壊すことなくそれを追加できるようにしたかったので、彼らはキーワードを予約しました。Java 5ではenumキーワードが追加され、それほど多くのコードを壊すことはありませんでした。

Javaは何を持っているがgoto、それはいくつかの構造を有していないいくつかの用途に対してその対応gotoつまりすることができること、breakおよびcontinue名前付きループを有します。また、finally一種のねじれたものと考えることもできますgoto


1

同じ名前の変数の宣言を禁止します。

例えば int i = 0, goto;


3
しかし、なぜですか?なぜ私たちはこれらの宣言をすることを許されるべきではないのですか?
DarknessFishへの接近

1

これは、あなたがしてはいけないことの1つと考えられていますが、開発者の混乱を避けるために予約語としてリストされていたと思われます。


1

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto

Javaにgotoステートメントがないと言われたら、だまされました。実際、Javaは「ソース」コードの2つの層で構成されています。


5
それは、すべての言語の下にあるアセンブリコードに無条件分岐が存在するため、どの言語にもgotoがあると言っているようなものです。バイトコードにgotoがあることは、「in java」が「Java言語で」を意味し、バイトコードがソースのレイヤーではないため、Javaにgotoがあることを意味しません。

@ tgm1024、「Java内」は「Javaプラットフォーム内」とも解釈できます。JavaコンパイラはJavaバイトコードを生成する必要があるか、JavaプラットフォームJVMでは出力が機能しません。たとえば、C ++はコンパイル出力を指定せず、コンパイラーは任意の形式のマシンコード(またはその他のコード)を自由に生成できます。Javaバイトコードでプログラミングされたアプリケーションは「Javaアプリケーション」と呼ぶことができますが、マシンコードでプログラミングされたアプリケーションは「C ++アプリケーション」と呼ぶことはできません。
MikaelLindlöf、2015

2
私はjavaバイトコードが何であるかをよく知っています。私は1996年に初めてJavaでコーディングしました。他の言語でJVM用のJavaバイトコードを生成することもできます。私があなたを訂正しているところは、2つの層のソースがあるというこの考えです。存在しません。Javaソースがあり、これはJavaバイトコード(JVMによって実行される)にコンパイルされており、ソースの追加レイヤーではありません。バイトコードに「goto」があるからといって、Javaに「goto」があるという意味ではありません。Javaは、breaksとcontinueを指名していますが、gotoは指定していません。

@ tgm1024私は反対投票によって起こされました:)最後のコメントをし、あなたの資格情報が印象的だったので、私は議論を失ったように思われます。私が構築してきた私のポイントは、Javaバイトコードでプログラムすることは非常に可能であるということでした。:あなたを確保するために、ここではそのことについてさえ疑問だstackoverflow.com/questions/3150254/...
ミカエルLindlöf


1

goto通常はコードが読みにくくなるので、私はどちらも好きではありません。ただし、そのルールには例外があると思います(特に、レクサーとパーサーに関しては!)

もちろん、プログラムをアセンブラのようなものに翻訳して、次のように書くことで、いつでもプログラムをKleene Normalformに取り込むことができます。

int line = 1;
boolean running = true;
while(running)
{
    switch(line++)
    {
        case 1: /* line 1 */
                break;
        case 2: /* line 2 */
                break;
        ...
        case 42: line = 1337; // goto 1337
                break;
        ...
        default: running = false;
                break;
    }
}

(基本的に、バイナリコードを実行するVMを記述します。ここでline、命令ポインターに対応します)

これは、を使用するコードよりもはるかに読みやすいgotoでしょう。


次の質問、「Pythonにはswitch文がありますか」
Mark K Cowan

0

もちろんそれはキーワードですが、ソースコードのレベルでは使用されません。

しかし、バイトコードに変換されるjasminまたは他の低レベル言語を使用する場合、「goto」が存在します


-1

Java言語はそれを使用しませんが、JVMバイトコードは使用するためです。


7
では、なぜ言語にはloadキーワードがないのでしょうか?
DarknessFishへの接近

3
@gribnit、バイトコードでgotoを実行すること自体は、上位レベルの予約語には何の意味もありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.