Program Club

Java 레이블 문 사용을 피해야합니까?

proclub 2020. 11. 10. 22:32
반응형

Java 레이블 문 사용을 피해야합니까?


오늘 저는 동료가 제가 만든 2 개의 중첩 된 for 루프를 통해 흐름을 제어하기 위해 레이블 문을 사용하도록 코드를 리팩터링하도록 제안했습니다. 개인적으로 프로그램의 가독성을 떨어 뜨린다 고 생각하기 때문에 이전에 사용한 적이 없습니다. 그러나 논쟁이 충분히 확실하다면 나는 그것들을 사용하는 것에 대해 마음을 바꿀 의향이 있습니다. 라벨 문구에 대한 사람들의 의견은 무엇입니까?


두 개의 루프 (또는 switch 문을 포함하는 루프)를 건너 뛸 수 있으면 많은 알고리즘이 더 쉽게 표현됩니다. 그것에 대해 나쁘게 느끼지 마십시오. 반면에 지나치게 복잡한 솔루션을 나타낼 수 있습니다. 그러니 물러서서 문제를보세요.

어떤 사람들은 모든 루프에 대해 "단일 진입, 단일 종료"접근 방식을 선호합니다. 즉, 중단 (및 계속)을 피하고 for 루프를 조기에 반환하는 것입니다. 이로 인해 일부 중복 코드가 발생할 수 있습니다.

내가 강하게 피하고 싶은 것은 보조 변수를 도입하는 것입니다. 상태 내에서 제어 흐름을 숨기면 혼란이 가중됩니다.

레이블이 지정된 루프를 두 가지 방법으로 분할하는 것은 어려울 수 있습니다. 예외는 아마도 너무 무겁습니다. 단일 진입, 단일 출구 접근 방식을 시도하십시오.


레이블 고토의 같다 : 그들을 아껴서 사용하고, 그들 만이 코드를 빠르게 할 때 더 중요한 것은, 더 이해할 수있는,

예를 들어, 6 단계 깊이의 큰 루프에 있고 나머지 루프를 완료 할 무의미하게 만드는 조건이 발생하는 경우 조건문에 6 개의 추가 트랩 도어가있어 루프를 일찍 종료하는 것은 의미가 없습니다.

레이블 (및 고토)은 악한 것이 아니라 때때로 사람들이 나쁜 방식으로 사용하기 때문입니다. 대부분의 경우 우리는 실제로 코드를 작성하려고하므로 여러분과 다음 프로그래머가 이해할 수 있습니다. 초고속으로 만드는 것은 부차적 인 문제입니다 (조기 최적화에주의하십시오).

레이블 (및 goto)이 오용되면 코드를 읽을 수 없게되어 사용자와 다음 개발자에게 슬픔이 생깁니다. 컴파일러는 상관하지 않습니다.


레이블이 필요한 경우는 거의 없으며 거의 ​​사용되지 않기 때문에 혼란 스러울 수 있습니다. 그러나 하나를 사용해야하는 경우 하나를 사용하십시오.

BTW : 이것은 컴파일되고 실행됩니다.

class MyFirstJavaProg {  
        public static void main(String args[]) {
           http://www.javacoffeebreak.com/java101/java101.html
           System.out.println("Hello World!");
        }
}

레이블에 대한 대안이 무엇인지 듣고 싶습니다. 나는 이것이 "가능한 한 빨리 반환"대 "변수를 사용하여 반환 값을 유지하고 끝에서만 반환"이라는 주장으로 귀결 될 것이라고 생각합니다.

레이블은 중첩 루프가있을 때 매우 표준입니다. 그들이 진정으로 가독성을 감소시키는 유일한 방법은 다른 개발자가 전에 본 적이없고 의미를 이해하지 못하는 경우입니다.


Java 코드에서 "야생"으로 사용되는 레이블을 본 적이 없습니다. 중첩 된 루프를 중단하고 싶다면 초기 return 문이 원하는 작업을 수행하도록 메서드를 리팩터링 할 수 있는지 확인하세요.

엄밀히 말하면 조기 복귀와 레이블 사이에는 큰 차이가 없다고 생각합니다. 그러나 실질적으로 거의 모든 Java 개발자는 조기 복귀를 보았고 그 기능을 알고 있습니다. 나는 많은 개발자들이 적어도 레이블에 놀라고 아마도 혼란 스러울 것이라고 생각합니다.

저는 학교에서 단일 진입 / 단일 퇴장에 대한 정통성을 배웠지 만 이후로 코드를 단순화하고 명확하게 만드는 방법으로 초기 반환 진술과 루프 탈피에 감사하게되었습니다.


나는 몇몇 지역에서 그것들을 선호한다고 주장하고,이 예제에서 특히 유용하다는 것을 알았습니다.


nextItem: for(CartItem item : user.getCart()) {

  nextCondition : for(PurchaseCondition cond : item.getConditions()) {
     if(!cond.check())
        continue nextItem;
     else
        continue nextCondition;

  }
  purchasedItems.add(item);
}

새로운 for-each 루프를 사용하면 레이블이 정말 명확해질 수 있다고 생각합니다.

예를 들면 :

sentence: for(Sentence sentence: paragraph) {
  for(String word: sentence) {
    // do something
    if(isDone()) {
      continue sentence;
    }
  }
}

새로운 for-each의 변수와 동일한 레이블을 사용하면 정말 명확 해 보입니다. 사실 Java는 악의적이어야하며 각 변수에 대한 암시 적 레이블을 추가해야합니다.


I have use a Java labeled loop for an implementation of a Sieve method to find prime numbers (done for one of the project Euler math problems) which made it 10x faster compared to nested loops. Eg if(certain condition) go back to outer loop.

private static void testByFactoring() {
    primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) {
        int toTest = m_toFactor[ctr];
        for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) {
            // max (int) Math.sqrt(m_numberToTest) + 1 iterations
            if (toTest != m_divisors[ctr2]
                        && toTest % m_divisors[ctr2] == 0) {
                continue primes; 
            }
        } // end of the divisor loop
    } // end of primes loop
} // method

I asked a C++ programmer how bad labeled loops are, he said he would use them sparingly, but they can occasionally come in handy. For example, if you have 3 nested loops and for certain conditions you want to go back to the outermost loop.

So they have their uses, it depends on the problem you were trying to solve.


I never use labels in my code. I prefer to create a guard and initialize it to null or other unusual value. This guard is often a result object. I haven't seen any of my coworkers using labels, nor found any in our repository. It really depends on your style of coding. In my opinion using labels would decrease the readability as it's not a common construct and usually it's not used in Java.


Yes, you should avoid using label unless there's a specific reason to use them (the example of it simplifying implementation of an algorithm is pertinent). In such a case I would advise adding sufficient comments or other documentation to explain the reasoning behind it so that someone doesn't come along later and mangle it out of some notion of "improving the code" or "getting rid of code smell" or some other potentially BS excuse.

I would equate this sort of question with deciding when one should or shouldn't use the ternary if. The chief rationale being that it can impede readability and unless the programmer is very careful to name things in a reasonable way then use of conventions such as labels might make things a lot worse. Suppose the example using 'nextCondition' and 'nextItem' had used 'loop1' and 'loop2' for his label names.

Personally labels are one of those features that don't make a lot of sense to me, outside of Assembly or BASIC and other similarly limited languages. Java has plenty of more conventional/regular loop and control constructs.


I found labels to be sometimes useful in tests, to separate the usual setup, excercise and verify phases and group related statements. For example, using the BDD terminology:

@Test
public void should_Clear_Cached_Element() throws Exception {
    given: {
        elementStream = defaultStream();
        elementStream.readElement();
        Assume.assumeNotNull(elementStream.lastRead());
    }
    when:
        elementStream.clearLast();
    then:
        assertThat(elementStream.lastRead()).isEmpty();
}

Your formatting choices may vary but the core idea is that labels, in this case, provide a noticeable distinction between the logical sections comprising your test, better than comments can. I think the Spock library just builds on this very feature to declare its test phases.

참고URL : https://stackoverflow.com/questions/46496/should-i-avoid-using-java-label-statements

반응형