program tip

자바에서 goto 문에 대한 대안

radiobox 2020. 9. 21. 07:34
반응형

자바에서 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 기능이 필요하지 않습니다.


gotoJava 개념 과 직접적으로 동등한 것은 없습니다 . 클래식으로 할 수있는 작업 중 일부 를 수행 할 수있는 몇 가지 구성이 있습니다 goto.

  • breakcontinue문은 루프 또는 스위치 문에서 블록 밖으로 점프 할 수 있습니다.
  • 레이블이 지정된 문 break <label>으로 임의의 복합 문에서 주어진 메서드 (또는 이니셜 라이저 블록) 내의 모든 수준으로 이동할 수 있습니다.
  • 루프 문에 레이블 continue <label>을 지정하면 내부 루프에서 외부 루프의 다음 반복을 계속할 수 있습니다 .
  • 예외를 던지고 잡으면 여러 수준의 메서드 호출에서 (효과적으로) 점프 할 수 있습니다. (그러나 예외는 상대적으로 비용이 많이 들고 "일반적인"제어 흐름 1 을 수행하는 잘못된 방법으로 간주됩니다 .)
  • 물론 return.

이러한 Java 구성 중 어느 것도 현재 명령문과 동일한 중첩 수준에있는 코드의 한 지점 또는 역방향 분기를 허용하지 않습니다. 그들은 모두 하나 이상의 중첩 (범위) 레벨을 continue뛰어 내리고 모두 (제외 ) 아래로 점프합니다. 이 제한은 이전 BASIC, FORTRAN 및 COBOL 코드 2에 내재 된 goto "스파게티 코드"증후군을 방지하는 데 도움이됩니다 .


1- 예외 중 가장 비용이 많이 드는 부분은 예외 개체와 스택 추적의 실제 생성입니다. 정말로 "정상"흐름 제어를 위해 예외 처리를 사용해야하는 경우 예외 개체를 미리 할당 / 재사용하거나 fillInStackTrace()메서드 를 재정의하는 사용자 지정 예외 클래스를 만들 수 있습니다 . 단점은 예외의 printStackTrace()메서드가 유용한 정보를 제공하지 않는다는 것입니다.

2-스파게티 코드 신드롬은 사용 가능한 언어 구조의 사용을 제한 하는 구조적 프로그래밍 접근 방식을 생성했습니다. 이것은 BASIC , FortranCOBOL에 적용될 수 있지만주의와 규율이 필요했습니다. 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!

"사용하지 마십시오!"를 추가해야합니까?


While some commenters and downvoters argue that this isn't goto, the generated bytecode from the below Java statements really suggests that these statements really do express goto semantics.

Specifically, the do {...} while(true); loop in the second example is optimised by Java compilers in order not to evaluate the loop condition.

Jumping forward

label: {
  // do stuff
  if (check) break label;
  // do more stuff
}

In bytecode:

2  iload_1 [check]
3  ifeq 6          // Jumping forward
6  ..

Jumping backward

label: do {
  // do stuff
  if (check) continue label;
  // do more stuff
  break label;
} while(true);

In bytecode:

 2  iload_1 [check]
 3  ifeq 9
 6  goto 2          // Jumping backward
 9  ..

If you really want something like goto statements, you could always try breaking to named blocks.

You have to be within the scope of the block to break to the label:

namedBlock: {
  if (j==2) {
    // this will take you to the label above
    break namedBlock;
  }
}

I won't lecture you on why you should avoid goto's - I'm assuming you already know the answer to that.


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 writes:

There are two constructs that allow you to do some of the things you can do with a classic goto.

One more...

Matt Wolfe writes:

People always talk about never using a goto, but I think there is a really good real world use case which is pretty well known and used.. That is, making sure to execute some code before a return from a function.. Usually its releasing locks or what not, but in my case I'd love to be able to jump to a break right before the return so I can do required mandatory cleanup.

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

The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.

The silly interview question associated with finally is: If you return from a try{} block, but have a return in your finally{} too, which value is returned?


The easiest is:

int label = 0;
loop:while(true) {
    switch(state) {
        case 0:
            // Some code
            state = 5;
            break;

        case 2:
            // Some code
            state = 4;
            break;
        ...
        default:
            break loop;
    }
}

Try the code below. It works for me.

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++) {"

Use a labeled break as an alternative to goto.


Java doesn't have goto, because it makes the code unstructured and unclear to read. However, you can use break and continue as civilized form of goto without its problems.


Jumping forward using break -

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");

Output:

Before Break
After ahead

Jumping backward using continue

before: {
    System.out.println("Continue");
    continue before;
}

This will result in an infinite loop as every time the line continue before is executed, the code flow will start again from before.

참고URL : https://stackoverflow.com/questions/2430782/alternative-to-a-goto-statement-in-java

반응형