Следует ли мне избегать использования операторов меток Java?

StackOverflow https://stackoverflow.com/questions/46496

  •  09-06-2019
  •  | 
  •  

Вопрос

Сегодня мой коллега предложил мне провести рефакторинг моего кода, чтобы использовать оператор метки для управления потоком через два вложенных цикла for, которые я создал.Я никогда раньше не использовал их, поскольку лично считаю, что они ухудшают читабельность программы.Однако я готов изменить свое мнение об их использовании, если аргументы достаточно веские.Каково мнение людей о заявлениях на этикетке?

Это было полезно?

Решение

Многие алгоритмы можно выразить проще, если вы можете перепрыгнуть через два цикла (или цикл, содержащий оператор переключения).Не расстраивайтесь из-за этого.С другой стороны, это может указывать на слишком сложное решение.Так что отойдите и посмотрите на проблему.

Некоторые люди предпочитают подход «один вход – один выход» для всех циклов.То есть вообще избегать прерывания (и продолжения) и раннего возврата циклов.Это может привести к дублированию кода.

Чего бы я категорически не делал, так это введения вспомогательных переменных.Сокрытие потока управления внутри состояния добавляет путаницы.

Разделение помеченных циклов на два метода может оказаться затруднительным.Исключения, вероятно, слишком тяжелы.Попробуйте подход «один вход – один выход».

Другие советы

Метки похожи на goto:Используйте их экономно и только тогда, когда они ускоряют ваш код. и что более важно, более понятно,

например, если вы находитесь в больших циклах глубиной шесть уровней и столкнулись с условием, которое делает остальную часть цикла бессмысленной для завершения, нет смысла иметь в ваших операторах условия 6 дополнительных ловушек для досрочного выхода из цикла.

Метки (и переходы) не являются злом, просто иногда люди используют их неправильным образом.Большую часть времени мы на самом деле пытаемся написать наш код так, чтобы он был понятен вам и следующему программисту, который придет.Сделать его сверхбыстрым — второстепенная задача (остерегайтесь преждевременной оптимизации).

Когда метки (и переходы) используются неправильно, они делают код менее читабельным, что причиняет горе вам и следующему разработчику.Компилятору все равно.

Метки нужны в редких случаях, и они могут сбивать с толку, поскольку используются редко.Однако, если вам нужно использовать один, используйте его.

КСТАТИ:это компилируется и запускается.

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

Мне интересно услышать, какая у вас альтернатива ярлыкам.Я думаю, что это в значительной степени сводится к аргументу «возвращение как можно раньше» против «возвращения как можно раньше».«используйте переменную для хранения возвращаемого значения и возвращайте ее только в конце».

Метки довольно стандартны, если у вас есть вложенные циклы.Единственный способ, которым они действительно ухудшают читабельность, — это когда другой разработчик никогда их раньше не видел и не понимает, что они означают.

Я никогда не видел, чтобы метки использовались «в дикой природе» в коде Java.Если вы действительно хотите преодолеть вложенные циклы, посмотрите, сможете ли вы реорганизовать свой метод так, чтобы ранний оператор возврата делал то, что вы хотите.

Технически, я думаю, нет большой разницы между ранним возвращением и лейблом.Однако на практике почти каждый 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 должна быть злой и добавлять неявные метки для каждой переменной, хех

Я использовал цикл с меткой Java для реализации метода Sieve для поиска простых чисел (сделано для одной из математических задач Эйлера в проекте), что сделало его в 10 раз быстрее по сравнению с вложенными циклами.Например, если (определенное условие) вернуться во внешний цикл.

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

Я спросил программиста C++, насколько плохи помеченные циклы, и он сказал, что будет использовать их экономно, но иногда они могут пригодиться.Например, если у вас есть 3 вложенных цикла и при определенных условиях вы хотите вернуться к самому внешнему циклу.

Итак, у них есть свое применение, это зависит от проблемы, которую вы пытались решить.

Я никогда не использую метки в своем коде.Я предпочитаю создать защиту и инициализировать ее нулевой или другое необычное значение.Этот охранник часто является объектом результата.Я не видел, чтобы кто-либо из моих коллег использовал ярлыки, и не нашел их в нашем репозитории.Это действительно зависит от вашего стиля кодирования.По моему мнению, использование меток ухудшит читабельность, поскольку это нестандартная конструкция и обычно она не используется в Java.

Да, вам следует избегать использования меток, если для их использования нет особой причины (уместен пример упрощения реализации алгоритма).В таком случае я бы посоветовал добавить достаточное количество комментариев или другую документацию, чтобы объяснить причину этого, чтобы кто-то позже не пришел и не исказил это из-за какого-то понятия «улучшение кода» или «избавление от запаха кода» или какое-то другое потенциально глупое оправдание.

Я бы приравнял этот вопрос к решению, когда следует или не следует использовать троичный if.Основное обоснование заключается в том, что это может ухудшить читаемость, и если программист не будет очень осторожен с разумным наименованием вещей, то использование соглашений, таких как метки, может значительно ухудшить ситуацию.Предположим, что в примере с использованием «nextCondition» и «nextItem» в качестве имен меток использовались «loop1» и «loop2».

Лично для меня метки — это одна из тех функций, которые не имеют особого смысла за пределами ассемблера, BASIC и других столь же ограниченных языков.В Java есть множество более традиционных/обычных конструкций циклов и управления.

Я обнаружил, что метки иногда полезны в тестах, чтобы разделить обычную настройку, упражнения и проверки фаз, а также сгруппировать связанные утверждения.Например, используя терминологию BDD:

@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();
}

Варианты форматирования могут различаться, но основная идея заключается в том, что метки в этом случае обеспечивают заметное различие между логическими разделами, составляющими ваш тест, лучше, чем это могут сделать комментарии.я думаю Спок библиотека просто использует эту функцию для объявления этапов тестирования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top