web-dev-qa-db-ja.com

Javaにgoto文はありますか?

私はこれについて混乱しています。私たちのほとんどは、Javaにはgoto文がないと言われてきました。

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

245
Venkat

Javaキーワードリストgotoキーワードを指定しますが、 "未使用"としてマークされています。

これは元のJVMにありました( @VitaliiFedorenkoの回答を参照 )。その後削除されました。将来のバージョンのJavaに追加される予定の場合は、おそらく予約キーワードとして保管されていました。

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

189
Thomas

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

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

215

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

私が考えることができる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;
    }
}
144
jonnystoten

http://Java.Sun.com/docs/books/tutorial/Java/nutsandbolts/_keywords.html

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

43
Isaac E

そのため、言語デザイナーがその必要性を感じたら、いつかそれらを使用することができます。

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

それとも、goto :)を使ってプログラマを止めただけかもしれません。

29
dave

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

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

なぜJavaにgoto文がないのかは、「 The Java Language Environment 」にあります。

Javaにはgoto文はありません。後藤は単に「そこにあるから」というよりは(誤って)使用されることを研究は示しています。 gotoを排除することは言語の単純化につながりました - 例えば、for文の途中にgotoの効果に関する規則はありません。およそ10万行のCコードを調べた結果、gotoステートメントのおよそ90パーセントが、入れ子になったループから抜け出す効果を得るためだけに使用されていたことがわかりました。上記のように、複数レベルのブレークと継続は、gotoステートメントの必要性の大部分を取り除きます。

19
Heinzi

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

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
17
andrew

いいえ、gotoは使用されませんが、ラベルを定義してそのラベルまでループを残すことができます。ラベルに続けてbreakまたはcontinueを使用できます。そのため、複数のループレベルを飛び越えることができます。チュートリアル を見てください

10
Arne Burmeister

goto構文は、プログラマが機械語とアセンブリ言語でプログラミングしていた時代から残っていることを理解することが重要です。これらの言語はとても基本的なので(のように、各命令は 1 ということですが、プログラム制御フローはgotoステートメントで完全に行われます(ただしアセンブリ言語では、これらは以下のように呼ばれます)。 ジャンプ または ブランチ 指示)。

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

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

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

10

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

gotoキーワードは予約されているだけで、使用されていません(constも同じです)。

9
Bozho

サポートされていないため、何もしなかったgotoキーワードまたはgotoという名前の変数が必要なのはなぜですか。

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

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");
     }
}
8
pjp

いいえ、gotoは予約語であるにもかかわらずJavaでは使用されません。 constについても同じことが言えます。これらは両方ともC++で使用されています。これがおそらくそれらが予約されている理由です。その意図はおそらく、C++プログラマーがJavaに移行するのを混乱させることを避けるためであり、おそらく後のバージョンのJavaでそれらを使用するという選択肢を維持するためでもありました。

7

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

Javaにはgotoはありませんが、gotoの用途に対応する、つまり名前付きループでbreakcontinueを使用できるようにするためのいくつかの構文があります。また、finallyは一種のねじれたgotoと考えることができます。

2
Thomas Pornin

Gotoの無害な使い方の大部分を次のように置き換えることができることに注意してください。

  • 戻る

  • ブレーク

  • breakラベル

  • try-catch-finallyの内側にスローします

2
starblue

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

Javaにgoto文がないと言われたならば、あなたはだまされています。実際、Javaは2層の「ソース」コードで構成されています。

1
Mikael Lindlöf

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

例えばint i = 0, goto;

1
Karl

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

1
Dean J

次のリンクを見ると、すべてのJava予約語が表示され、追加されたバージョンがわかります。

http://Java.Sun.com/docs/books/tutorial/Java/nutsandbolts/_keywords.html

gotoは現在使用されていないにもかかわらず予約されています。

1
Paul Whelan

私は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を使うコードよりもずっと読みやすいですね。

1

Java言語では使用されていませんが、JVMバイトコードでは使用されているからです。

0
gribnit

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

しかし、もしあなたがjasminやバイトコードに変換される他の低レベル言語を使っているならば、 "goto"はそこにあります

0
user1722245