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 구성 중 어느 것도 현재 명령문과 동일한 중첩 수준에있는 코드의 한 지점 또는 역방향 분기를 허용하지 않습니다. 그들은 모두 하나 이상의 중첩 (범위) 레벨을 continue
뛰어 내리고 모두 (제외 ) 아래로 점프합니다. 이 제한은 이전 BASIC, FORTRAN 및 COBOL 코드 2에 내재 된 goto "스파게티 코드"증후군을 방지하는 데 도움이됩니다 .
1- 예외에서 가장 비용이 많이 드는 부분은 예외 개체와 스택 추적의 실제 생성입니다. 정말로 "정상"흐름 제어에 예외 처리를 사용해야하는 경우 예외 개체를 미리 할당 / 재사용하거나 fillInStackTrace()
메서드 를 재정의하는 사용자 지정 예외 클래스를 만들 수 있습니다 . 단점은 예외의 printStackTrace()
메서드가 유용한 정보를 제공하지 않는다는 것입니다.
2-스파게티 코드 신드롬은 사용 가능한 언어 구조의 사용을 제한 하는 구조적 프로그래밍 접근 방식을 생성했습니다. 이것은 BASIC , Fortran 및 COBOL에 적용될 수 있지만주의와 규율이 필요했습니다. goto
완전히 제거 하는 것이 실용적으로 더 나은 해결책이었습니다. 언어로 보관하면 항상 그것을 남용하는 광대가 있습니다.
그냥 재미를 위해, 여기에 자바에서 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);
두 번째 예제의 루프는 루프 조건을 평가하지 않기 위해 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)
(A) 내로 컴파일러에 의해 번역 goto
바이트 동작. 으로 true
일정의 리터럴, 컴파일러는이 최적화를 할 수있는 아무것도를 평가하지 않습니다. 그래서, 내 예를 정말 뒤로 점프 고토는 ...이다
goto 문과 같은 것을 정말로 원한다면 항상 명명 된 블록으로 분리 할 수 있습니다.
레이블로 분리하려면 블록 범위 내에 있어야합니다.
namedBlock: {
if (j==2) {
// this will take you to the label above
break namedBlock;
}
}
고토를 피해야하는 이유에 대해서는 설명하지 않겠습니다. 이미 그에 대한 답을 알고 있다고 가정합니다.
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로 할 수있는 일을 할 수있는 두 가지 구조가 있습니다.
하나 더...
Matt Wolfe는 다음과 같이 씁니다.
사람들은 항상 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 블록은 try 블록이 종료 될 때 항상 실행됩니다. 이렇게하면 예기치 않은 예외가 발생하더라도 finally 블록이 실행됩니다. 그러나 마지막으로 예외 처리 이상의 용도로 유용합니다. 프로그래머가 반환, 계속 또는 중단으로 인해 실수로 정리 코드를 우회하는 것을 방지 할 수 있습니다. 정리 코드를 finally 블록에 넣는 것은 예외가 예상되지 않는 경우에도 항상 좋은 방법입니다.
finally와 관련된 어리석은 인터뷰 질문은 다음과 같습니다. try {} 블록에서 돌아 왔지만 finally {}에도 반환이있는 경우 어떤 값이 반환됩니까?
return
A의 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
? 그 안에 더 중요한 문제가 있다고 생각합니다.