Java에는 goto 문이 있습니까?


259

나는 이것에 대해 혼란스러워한다. 우리 대부분은 Java에 goto 문이 없다고 들었습니다.

그러나 나는 그것이 Java의 키워드 중 하나라는 것을 알았습니다. 어디에서 사용할 수 있습니까? 사용할 수 없다면 왜 키워드로 Java에 포함 되었습니까?


13
충고 한마디 : goto를 사용하지 마십시오
lostiniceland

16
그리고 " '유해한 것으로 간주되는 진술서에 해로운 것으로 간주 됨"및 "'"유해한 것으로 간주되는 진술서로 가기 "가 유해한 것으로 간주 됨 '이 있습니다." VEEEEERY 재귀,이 밈.
Chris Charabaruk

70
'goto'는 'goto work'또는 'goto school'과 같이 항상 악합니다.)
Andreas Dolk

24
실제 이유는 "g ** o"단어가 대부분의 프로그래밍 언어에서 음란 한 것으로 간주되기 때문입니다. 자바 디자이너들은 무고한 젊은 프로그래머들을 부패시키는 영향으로부터 보호하고 있습니다. (:-))
Stephen C

25
고토에 대한 마녀 사냥은 내 인생에서 가장 가혹한 순간을 낳았습니다. 나는 사람들이 함수에 기능을 숨기고 C 코드를 왜곡하는 것을 보았습니다. 멀티 중첩 루프에 터무니없는 종료 논리를 넣은 다음 코드 검토에서 코드를 비판하는 사람을 피하기 위해 상상할 수있는 모든 JUST를 상상하십시오. 이 규칙은 "여러 번의 반품을 피해야합니다"canard와 함께 말도 안됩니다. goto로 인해 유지 관리가 어려운 경우가 있습니다. goto로 인해 유지 관리가 더 쉬워지는 경우가 있습니다. 이 마녀 사냥이 80 년대에 죽었기를 바랐습니다.

답변:


200

자바 키워드 목록은 지정 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

2
그것은 유익하고 흥미로운 정보이지만 그것이 여전히 예약 된 키워드 인 이유를 설명하지는 않습니다.
Thomas

@Thomas 왜 예약되어 있는지 설명하지 않았습니까? 키워드이므로 지금 사용할 수 없습니다. 나중에 goto는 문제를 일으키지 않고 생겨날 수있었습니다. 예약어가 아닌 경우 goto가 도입되면 중단되는 코드 (int goto = 2;)를 생성하는 데 사용할 수 있습니다.

230

James Gosling은 goto명령문 을 지원하여 원래 JVM을 작성 했지만이 기능을 불필요하게 제거했습니다. 주된 이유 goto는 일반적으로 더 읽기 쉬운 문장으로 대체 break/continue하거나 (예 :) 코드 조각을 메소드로 추출하여 대체 할 수 있기 때문 입니다.

출처 : James Gosling, Q & A 세션


24
"... 또는 코드 조각을 메소드로 추출하여"-적절한 테일 콜 제거 없이는 매우 시원해야합니다.
표시 이름

45
때때로의 현명한 사용하는 goto 것입니다 무엇으로 강제하는 것은 억지로 그래서 무언가를 표현하는 가장 readyble하고 명확한 방법은 덜 읽을 수 .
중복 제거기

1
@Deduplicator goto의 사용은 적절할 경우 항상 오류가 발생하기 쉽습니다.
Çelebi Murat

@Deduplicator C ++에서 좋은 pratice로 간주되는 goto의 유일한 사용은 break / continue에 의해 뒷받침됩니다.
겨울

2
Java에서 예약 키워드 인 Goto는 사람들이 "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 No-첫 번째 루프 직전에 코드를 레이블로 리디렉션합니다.
assylias

21
@assylias 글쎄요. 레이블은 외부 루프에 레이블을 지정합니다. 그런 다음 break loops""라는 루프에서 벗어남을 의미 loops합니다. 아마도 돌이켜 보면 레이블의 이름이 더 좋았을 것 outer입니다.
jonnystoten

8
"goto를 사용해야하는 유일한 이유"무조건 무한 루프가 필요한 빠르고 더러운 프로그램은 goto를 잘 활용합니다. while (true) {...를 사용하면 }과잉입니다. GOTO는 종종 부적절한 용도로 낙인 찍히지 만, 부울 리터럴에 대한 불필요한 비교는 GOTO보다 나쁘다고 주장합니다.
Alexander-복원 Monica Monica

1
루프 레이블이 루프 다음에 없어야합니까?
GC_

1
나는 최근에이 라벨링 기법이 continue LABEL;문장 과 함께 매우 유용하다는 것을 발견했다 . 따라서 외부 거짓말 루프를 계속할 수 있습니다.
infotoni91


29

언어 디자이너가 필요하다고 느끼면 언젠가 사용할 수 있습니다.

또한 이러한 키워드가있는 언어 (예 : C, C ++)의 프로그래머가 실수로 키워드를 사용하는 경우 Java 컴파일러가 유용한 오류 메시지를 표시 할 수 있습니다.

아니면 goto를 사용하여 프로그래머를 멈추는 것일 수도 있습니다. :)


Java에서 누락 된 goto 기능은 goto를 사용하지 않을 정도로 충분한 이유 여야합니다. 키워드로 예약 할 필요가 없습니다. 당신의 논리에 따르면, 모든 언어가 다른 언어에 의해 사용되거나 Java 디자이너가 미래에 그것을 사용할 수 있기 때문에 모든 것이 키워드가 될 것입니다.
stuXnet

1
나는 나의 논리가 모든 것이 키워드라는 것을 암시한다고 생각하지 않는다. Java에서 유용하게 감지 및 처리 할 수있는 여러 프로그래밍 언어에서 사용되는 작은 키워드 세트가 있습니다. 자바 는 자사의 C / C ++ 유산을 예약 goto하고 const반영했지만 아직 구현되지 않았다 (후자를 구현하는 것에 대한 논쟁이 있었음에도 불구하고). 이상과 같은 몇 가지 assertenum처음 아마도 예약,하지만했다가되어 그들이 구현되어 준해야한다. 그러나 후시는 훌륭한 것입니다.
dave

19

나중에 사용하기 위해 예약되어 있습니다 ( Java 언어 키워드 참조 ).

키워드 const와 goto는 현재 사용되지 않더라도 예약되어 있습니다.

그 이유 자바에는 고토 문 "에서 발견 할 수있다 Java 언어 환경 "

Java에는 goto 문이 없습니다. 연구에 따르면 goto는 단순히 "있는 이유"가 아니라 자주 사용됩니다. goto를 제거하면 언어가 단순화되었습니다. 예를 들어 for 문 중간에 goto의 영향에 대한 규칙은 없습니다. 약 10 만 줄의 C 코드에 대한 연구에 따르면 대략 90 %의 goto 문의가 순전히 중첩 루프에서 벗어날 수있는 효과를 얻는 데 사용 된 것으로 나타났습니다. 위에서 언급했듯이, 다단계 나누기와 계속해서 goto 문의 필요성을 대부분 제거합니다.


goto예약되어 있지만 나중에 사용할 수 없습니다.
Lorne의 후작

17

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

10

goto프로그래머가 기계 코드 및 어셈블리 언어로 프로그래밍 한 시절부터 구성이 남아 있다는 것을 이해하는 것이 중요합니다 . 이러한 언어는 매우 기본적이므로 (각 명령어는 가지 작업 만 수행함) 프로그램 제어 흐름은 goto명령문으로 완전히 수행됩니다 (하지만 어셈블리 언어에서는 점프 또는 분기 명령어 라고 함 ).

이제 C 언어는 상당히 저수준이지만 매우 높은 수준의 어셈블리 언어로 생각할 수 있습니다. C의 각 문과 함수는 어셈블리 언어 명령어로 쉽게 나눌 수 있습니다. C는 오늘날 컴퓨터를 프로그래밍하는 주요 언어는 아니지만 임베디드 시스템과 같은 저수준 응용 프로그램에서 여전히 많이 사용됩니다. C의 함수는 어셈블리 언어의 함수와 매우 유사하기 때문에goto 에 포함 된 가 있습니다.

Java가 C / C ++의 진화라는 것은 분명합니다. Java는 C의 많은 기능을 공유하지만 더 많은 세부 사항을 추상화하므로 단순히 다르게 작성됩니다. Java는 매우 높은 수준의 언어이므로 goto함수, 각, for 및 while 루프와 같은 더 높은 수준의 구문이 프로그램 제어 흐름을 수행하는 경우 와 같은 낮은 수준의 기능을 가질 필요는 없습니다 . 하나의 기능에 있었고goto 다른 기능에 레이블을 지정 . 다른 함수가 반환되면 어떻게됩니까? 이 아이디어는 터무니 없다.

이것은 왜 자바가 goto문장을 포함하는지 아직 대답하지는 않지만 컴파일하지 못하게하지만, 왜 goto처음에는 저수준 응용 프로그램에서 사용되었으며 왜 그것이 합리적이지 않은지를 아는 것이 중요 합니다 자바에서 사용됩니다.


"프로그램 제어 흐름은 goto로 완전히 수행됩니다". 항상 무조건적인 것은 아닙니다.
피터 Mortensen

C / C ++에서는 한 함수에서 다른 함수의 레이블로 "goto"로 점프하는 것도 불가능합니다. C / C ++의 Goto는 단일 기능 블록으로 제한됩니다.
user2328447

"더 높은 수준의 구성이 필요할 때 goto와 같은 낮은 수준의 기능을 가질 필요는 없습니다"- "필요성과 충분 성"을 기억하십시오. 그것은 단지 "필요하지 않다"입니다. 따라서 이유가 없습니다. 이유 : 어셈블러의 JMP, BNE 등을 "높은 수준"으로 대체 한 "Goto"는 "실행 가능 코드"로 이동하려고하지만 Java는 바이트 코드이므로 "실행 가능"하지 않습니다. ;-)
reichhart

10

아니요, goto사용되지는 않지만 레이블을 정의하고 레이블까지 루프를 남겨 둘 수 있습니다. 레이블을 사용 break하거나 continue그 뒤에 올 수 있습니다 . 따라서 하나 이상의 루프 레벨을 뛰어 넘을 수 있습니다. 튜토리얼을 살펴보십시오 .


9

아뇨, 고맙게도 goto Java .

goto키워드는 예약 만 (동일 간다 사용되지 않는다 const).


여기서 예약 된 의미가 무엇인지 알 수 있습니까? 코드에서 goto와 const를 사용하는 것이 좋지 않은 경우 왜 예약합니까? 설명해 주시겠습니까?
Gopi

@Sri Kumar : @applechewer의 답변을 참조하십시오. 존재하지만 구현되지 않았습니다.
Valentin Rocher

1
@Sri Kumar : 예약 된 키워드는 변수 이름 또는 이와 유사한 이름으로 사용되지 않습니다. 이런 식으로, 이러한 키워드는 다른 방법으로 사용할 수있는 오래된 소스 코드를 손상시키지 않고 향후 Java 버전에서 구현 될 수 있습니다.
Peter Di Cecco

8

지원되지 않으므로 goto이름이 없거나 변수가없는 키워드를 원하는 이유goto 하십니까?

당신은 사용할 수 있지만 break label;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라는 변수 나 메소드를 가질 수 없습니까?
Michael Borgwardt

4
프로그래밍 영역에서 의미가 있기 때문에 Java에는 적용되지 않습니다. 또한 변수 이름을 잘못 선택했습니다.
pjp

변수 'print'는 무엇에 사용됩니까? 언급 한 단어는 변수 나 키워드보다 메소드 이름과 유사합니다.
pjp

3
-1 : 우선, Java가 "goto"흐름 제어 명령문을 지원하지 않는다고해서 이것이 아무것도하지 않는 "goto"키워드가있는 이유는 아닙니다. 둘째, "goto"는 변수 이름이 좋지 않을 수도 있지만 "goto"가 키워드이기 때문에 사용할 수없는 훌륭한 메소드 이름 일 수 있습니다. 셋째, "중단 레이블"및 "연속 레이블"은 매우 적절한 이유로 존재하므로 "권장하지 않음"은 그다지 유용하지 않습니다. 넷째, 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

7

아니, goto예약어 임에도 불구하고, 자바에서 사용되지 않습니다. 의 경우도 마찬가지입니다 const. 둘 다 C ++에서 사용되는데, 이것이 예약 된 이유 일 것입니다. 의도는 아마도 C ++ 프로그래머가 Java로 마이그레이션하는 것을 혼동하지 말고 나중에 Java 개정판에서 사용하는 옵션을 유지하는 것이 었습니다.


1
나는 goto가까운 장래에 최소한 지원되지 않기를 정말로 바란다 .)
Bozho

6
@Bozho : 음, 그것은 오래된 "유해한"고토와 전혀 관련이없는 독창적 인 새로운 기능에 사용될 있습니다.
Michael Borgwardt

3

goto의 모든 양성 사용을 다음과 같이 대체 할 수 있습니다.

  • 반환

  • 단절

  • 브레이크 라벨

  • try-catch-finally 안으로 던져


5
흐름 제어에는 예외를 사용해서는 안됩니다
ChssPly76

13
흐름 제어에는 예외 사용되지만 예외적 인 경우에만 사용해야합니다. 예를 들어, C에서 goto를 사용하는 것 중 하나는 특히 처리와 관련된 경우 오류 처리입니다.
starblue

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, 즉 명명 된 루프 breakcontinue함께 사용할 수 있는 일부 구문이 있습니다. 또한 finally일종의 뒤틀린 것으로 생각할 수 있습니다 goto.


1

이름이 같은 변수 선언을 금지합니다.

예 : int i = 0, goto;


3
그런데 ? 왜 이런 선언을해서는 안됩니까?
ApproachingDarknessFish

1

그것은 당신이하지 말아야 할 것들 중 하나라고 많이 여겨지지만, 개발자를 혼동하지 않기 위해 예약어로 나열되었을 것입니다.


1

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

Java에 goto 문이 없다고 들었다면 당신은 바보입니다. 실제로 Java는 두 가지 '소스'코드 계층으로 구성됩니다.


5
그것은 어셈블리 코드 내에 무조건적인 브랜치가 있기 때문에 어떤 언어라도 사용한다고 말하는 것과 같습니다. 바이트 코드에 goto가 있다고해서 "in java"가 "Java 언어"를 의미하고 바이트 코드가 소스의 계층이 아니기 때문에 java에 goto가있는 것은 아닙니다.

@ tgm1024, "Java에서"는 "Java 플랫폼에서"로 해석 될 수도 있습니다. Java 컴파일러는 Java 바이트 코드를 생성해야합니다. 그렇지 않으면 Java 플랫폼 JVM에서 출력이 작동하지 않습니다. 예를 들어 C ++은 컴파일 출력을 지정하지 않으며 컴파일러는 어떤 형태의 기계 코드 (또는 다른 코드)도 자유롭게 생성 할 수 있습니다. Java 바이트 코드 프로그래밍 응용 프로그램은 "Java 응용 프로그램"이라고 할 수 있지만 기계 코드 프로그래밍 응용 프로그램은 "C ++ 응용 프로그램"이라고 할 수 없습니다.
Mikael Lindlöf

2
Java 바이트 코드가 무엇인지 잘 알고 있습니다. 1996 년에 Java로 처음 코딩했습니다. 그리고 다른 언어가 JVM의 Java 바이트 코드를 생성하도록 할 수 있습니다. 내가 수정하려는 곳은 두 가지 소스 계층이 있다는 아이디어입니다. 이 없습니다. 당신은 자바 소스를 가지고 있으며 이것은 자바 바이트 코드 (JVM에 의해 실행)로 컴파일되며 이것은 소스의 추가 레이어가 아닙니다. 바이트 코드에 "goto"가 있다고해서 Java에 "goto"가있는 것은 아닙니다. Java는 breaks로 명명되었고 계속 명명되었지만 goto는 없습니다.

@ tgm1024 나는 downvote에 의해 깨어났다. 필자가 구축 한 요점은 Java 바이트 코드로 프로그래밍 할 수 있다는 것입니다. 당신을 확신시키기 위해 여기에 대한 질문도 있습니다 : stackoverflow.com/questions/3150254/…
Mikael 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.


다음 질문, "파이썬에서 switch 문이 있습니까"
마크 K 코완

0

물론 키워드이지만 소스 코드 수준에서는 사용되지 않습니다.

그러나 jasmin 또는 다른 저수준 언어를 사용하여 바이트 코드로 변환하면 "goto"가 있습니다.


-1

Java 언어는 사용하지 않지만 JVM 바이트 코드는 사용합니다.


7
그러면 왜 언어에 load키워드가 없습니까?
ApproachingDarknessFish

3
@gribnit, 바이트 코드로 이동하는 것이 그 자체로 상위 예약어를 의미하는 것은 아닙니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.