Javaのgotoキーワードの代替関数は何ですか?
Javaにはgotoがないので。
Javaのgotoキーワードの代替関数は何ですか?
Javaにはgotoがないので。
回答:
ラベル付きのBREAKステートメントを使用できます。
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length; j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
ただし、適切に設計されたコードでは、GOTO機能は必要ありません。
goto
Javaの概念に直接相当するものはありません。クラシックでできることのいくつかを実行できるようにするいくつかの構造がありますgoto
。
break
そしてcontinue
文はループやスイッチ文でブロックからジャンプすることができます。break <label>
任意の複合ステートメントから、特定のメソッド(または初期化ブロック)内の任意のレベルにジャンプできます。continue <label>
と、内側のループから外側のループの次の反復を続行できます。return
。これらのJava構造はいずれも、現在のステートメントと同じレベルのネストで、コード内のあるポイントに逆方向に分岐することはできません。それらはすべて、1つ以上のネスト(スコープ)レベルからcontinue
飛び出し、(を除いて)すべて下にジャンプします。この制限は、古いBASIC、FORTRAN、およびCOBOLコード2に固有のgoto「スパゲッティコード」シンドロームを回避するのに役立ちます。
1-例外の最もコストのかかる部分は、例外オブジェクトとそのスタックトレースの実際の作成です。「通常の」フロー制御に本当に例外処理を使用する必要がある場合は、例外オブジェクトを事前に割り当て/再利用するか、fillInStackTrace()
メソッドをオーバーライドするカスタム例外クラスを作成できます。欠点は、例外のprintStackTrace()
メソッドが有用な情報を提供しないことです...それらを呼び出す必要がある場合。
2-スパゲッティコードシンドロームは、利用可能な言語構造の使用を制限する構造化プログラミングアプローチを生み出しました。これは、BASIC、Fortran、およびCOBOLに適用できますが、注意と規律が必要でした。goto
完全に取り除くことは、実用的に優れた解決策でした。あなたがそれを言語で保つならば、それを乱用する何人かの道化師が常にいます。
楽しみのためだけに、ここではJavaでGOTOの実装があります。
例:
1 public class GotoDemo { 2 public static void main(String[] args) { 3 int i = 3; 4 System.out.println(i); 5 i = i - 1; 6 if (i >= 0) { 7 GotoFactory.getSharedInstance().getGoto().go(4); 8 } 9 10 try { 11 System.out.print("Hell"); 12 if (Math.random() > 0) throw new Exception(); 13 System.out.println("World!"); 14 } catch (Exception e) { 15 System.out.print("o "); 16 GotoFactory.getSharedInstance().getGoto().go(13); 17 } 18 } 19 }
それを実行する:
$ java -cp bin:asm-3.1.jar GotoClassLoader GotoDemo 3 2 1 0 Hello World!
「使わないで!」を追加する必要がありますか?
Math.random()
0を返すことができます。> =
一部のコメント提供者や反対派は、これはgotoではないと主張していますが、以下のJavaステートメントから生成されたバイトコードは、これらのステートメントが実際にgotoセマンティクスを表現していることを実際に示唆しています。
具体的にはdo {...} while(true);
、2番目の例のループは、ループ条件を評価しないようにJavaコンパイラーによって最適化されています。
label: {
// do stuff
if (check) break label;
// do more stuff
}
バイトコード:
2 iload_1 [check]
3 ifeq 6 // Jumping forward
6 ..
label: do {
// do stuff
if (check) continue label;
// do more stuff
break label;
} while(true);
バイトコード:
2 iload_1 [check]
3 ifeq 9
6 goto 2 // Jumping backward
9 ..
continue label
後方へのジャンプです
// do stuff
と// do more stuff
が関心のあるステートメントである場合、(もちろんステートメントのために)後方にジャンプするcontinue label
「効果があります」while(true)
。しかし、これがそれほど正確な質問であることに気づいていませんでした...
while(true)
コンパイラによって翻訳されたgoto
バイトコード操作。以下のようtrue
に一定のリテラルで、コンパイラは、この最適化を行うことができますし、何を評価する必要はありません。だから、私の例は本当に後藤で、後ろにジャンプしています...
gotoステートメントのようなものが本当に必要な場合は、いつでも名前付きブロックに分割してみることができます。
ラベルを破るには、ブロックの範囲内にいる必要があります。
namedBlock: {
if (j==2) {
// this will take you to the label above
break namedBlock;
}
}
gotoを避けるべき理由については説明しません-その答えはすでに知っていると思います。
public class TestLabel {
enum Label{LABEL1, LABEL2, LABEL3, LABEL4}
/**
* @param args
*/
public static void main(String[] args) {
Label label = Label.LABEL1;
while(true) {
switch(label){
case LABEL1:
print(label);
case LABEL2:
print(label);
label = Label.LABEL4;
continue;
case LABEL3:
print(label);
label = Label.LABEL1;
break;
case LABEL4:
print(label);
label = Label.LABEL3;
continue;
}
break;
}
}
public final static void print(Label label){
System.out.println(label);
}
StephenCは次のように書いています。
古典的なgotoでできることのいくつかを実行できるようにする2つの構造があります。
もう1つ...
マットウルフは書いています:
人々はいつもgotoを使わないことについて話しますが、かなりよく知られていて使われている本当に良い実世界のユースケースがあると思います。つまり、関数から戻る前に必ずコードを実行してください。通常はリリースされます。ロックかどうかはわかりませんが、私の場合は、必要なクリーンアップを実行できるように、戻る直前に休憩にジャンプできるようにしたいと思います。
try {
// do stuff
return result; // or break, etc.
}
finally {
// clean up before actually returning, even though the order looks wrong.
}
http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
試行ブロックが終了すると、finallyブロックは常に実行されます。これにより、予期しない例外が発生した場合でも、finallyブロックが確実に実行されます。しかし、最後に、例外処理だけでなく、プログラマーがリターン、続行、または中断によって誤ってクリーンアップコードをバイパスすることを回避できるようにします。例外が予想されない場合でも、finallyブロックにクリーンアップコードを配置することは常に良い習慣です。
finalに関連するばかげたインタビューの質問は次のとおりです。try{}ブロックから戻ったが、finally {}にも戻りがある場合、どの値が返されますか?
return
であるかを理解するためだけに、何が起こるかを知っている必要がありfinally
ます。(そして、知識が厳密に必要でなくても、私はそれを見つける好奇心を持っていなかったプログラマーによって心配されるでしょう...)
以下のコードを試してください。わたしにはできる。
for (int iTaksa = 1; iTaksa <=8; iTaksa++) { // 'Count 8 Loop is 8 Taksa
strTaksaStringStar[iCountTaksa] = strTaksaStringCount[iTaksa];
LabelEndTaksa_Exit : {
if (iCountTaksa == 1) { //If count is 6 then next it's 2
iCountTaksa = 2;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 2) { //If count is 2 then next it's 3
iCountTaksa = 3;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 3) { //If count is 3 then next it's 4
iCountTaksa = 4;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 4) { //If count is 4 then next it's 7
iCountTaksa = 7;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 7) { //If count is 7 then next it's 5
iCountTaksa = 5;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 5) { //If count is 5 then next it's 8
iCountTaksa = 8;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 8) { //If count is 8 then next it's 6
iCountTaksa = 6;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 6) { //If count is 6 then loop 1 as 1 2 3 4 7 5 8 6 --> 1
iCountTaksa = 1;
break LabelEndTaksa_Exit;
}
} //LabelEndTaksa_Exit : {
} // "for (int iTaksa = 1; iTaksa <=8; iTaksa++) {"
Javaにはgoto
、コードが構造化されておらず、読みにくくなるため、がありません。ただし、使用することができますbreak
し、continue
など文明の形後藤その問題なし。
ahead: {
System.out.println("Before break");
break ahead;
System.out.println("After Break"); // This won't execute
}
// After a line break ahead, the code flow starts from here, after the ahead block
System.out.println("After ahead");
出力:
Before Break
After ahead
before: {
System.out.println("Continue");
continue before;
}
これにより、行が実行されるたびにコードフローがから再開されるため、無限ループが発生します。continue before
before
goto
いただけますか?そこにはもっと重要な問題があると思います。