Комментарии 38
Обращайтесь, я поражен был, если честно, когда впервые увидел ))
удобная штука, когда надо прервать из вложенного цикла во внешний.
з.ы. но стоит отметить, что эта фича используется столь редко, что давно считается дурным тоном — т.е. если вам она понадобилась, то стоит присмотреться к коду, нельзя ли его написать иначе и лучше? (а в некоторых статических анализаторах, например, встроенном в Jetbrains Idea, есть даже предупреждения об использовании break,continue, меток и вложенных циклов)
Про брейк не знал, спасибо!
ограничение одно: метка не должна выходить за пределы циклаНепонятное ограничение, кстати. Программа на языке высокого уровня (т.е. reducible CFG) состоит из вложенных друг в друга statement'ов, каждый из которых имеет один вход и максимум один выход. 'break' позволяет переместится к выходу любого statement'а в иерархии. Было бы логично, если бы 'continue' позволяло то же самое для входа, но почему-то оно ограничено только входами в циклы.
для сравнения:
в бейсиках 80х годов каждый оператор обязан был иметь числовую метку (не совсем так, можно было группировать операторы) и называлась метка номером строки, а условные операторы не могли быть сложными (не было понятия {блок}), и потому постоянно приходилось использовать goto: в какой-то момент ненависть к такому принуждению визуально прыгать по частям кода зашкалила и оператор выдрали с корнем из всех языков
Критика goto
Похоже, что отлаживать спагетти-код никогда не приходилось.
вспомнил, что когда-то давно
>Критика goto
вот именно
> Похоже, что отлаживать спагетти-код никогда не приходилось.
Хех, какой только
someLabel: {
if(conditionA) {
//...
break someLabel;
}
if(conditionB) {
//...
break someLabel;
}
if(conditionC) {
//...
break someLabel;
}
}
Если выполниться одно из условий, то оператор break someLabel выведет выполнение из блока
при том, что assert может не работать совсем — все зависит от флагов запуска.
> strictfp
лучше не использовать float, а использовать double, а еще лучше — использовать StrictMath
> При вызове vararg-метода без аргументов всё равно создаётся пустой массив
что очень удобно в циклах, ну и логично, если помнить, что vararg — это всего лишь syntax sugar
> Выражение switch-case не поддерживает java.lang.Class
А для чего это может понадобиться? Нет ли специфичного запашка?
>
Нет, остальное вообще, извините, детсад, комментарий аж застрял.
А теперь скажите, кому это пригодилось в продакшене?
Если использовать assert, хорошо бы знать, как он работает. Как только он появился, сразу прочитал про него всё, а не остановился на выжимке, что появилась мол, новая функциональность в языке.
Switch-case тоже, базовая конструкция языка, вроде. Либо используем и знаем, как она работает, либо не удивляемся, что она имеет ограничения. Раньше вообще можно было только числа использовать. (Да, тут я рассматриваю char как число). И, на всякий случай, в case можно писать только константу/константное выражение.
Break и continue — я бы удивился, если бы не было возможности указать метку. Как уже говорили выше — если пишешь на java, хорошо бы понимать, откуда растут ноги.
Вызов vararg-метода без аргументов. У меня единственный вопрос, а почему вообще ожидается, что массив, который содержит аргументы, внезапно может оказаться и не массивом вовсе, а null? Тут же, вроде, всё логично: длина массива равна количеству аргументов. Ноль аргументов — массив длины ноль. Или у меня логика ущербная? И предвосхищая комментарий: «ну, производительность-же!», опять же, сошлюсь на логику.
int.class.isAssignableFrom(Integer.class) — ну autoboxing-же. Если об этом не задумываться или не знать о его существовании, то как же жить-то дальше? int.class != Integer.class туда же. Это же базовые понятия языка — примитивные и непримитивные типы.
А по вопросу, помогли ли эти знания в production, скажу, что мат-часть хорошо бы знать. Иначе использовать её на полную не получится. А если не знать, то процесс уже напоминает раскладывание грабель. И очень повезёт, если как в случае с switch — case, код просто не скомпилируется. Так что то, что подобные вещи не знают программисты, которые работают над тем же проектом, это очень даже мешает в production. Поскольку обидно наступать на грабли, подложенные коллегой, который просто не знает базовых вещей.
Switch-case тоже, базовая конструкция языка, вроде. Либо используем и знаем, как она работает, либо не удивляемся, что она имеет ограничения. Раньше вообще можно было только числа использовать. (Да, тут я рассматриваю char как число). И, на всякий случай, в case можно писать только константу/константное выражение.
Вам осталось сделать крошечный шаг до осознания того, что String.class
как раз и является постоянной. Я ведь недаром вписал пример про switch-case, эта конструкция не так проста, как кажется, но, похоже, почти никто не заметил скрытого смысла. Думаю, я сделаю про это отдельную запись.
Иными словами, на этапе компиляции значение данного выражения не может быть определено. Именно поэтому оно и не может быть использовано в case.
Class literal в case
нельзя использовать потому, что в JLS11 §14.11 его поддержка не заявлена:
The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, String, or an enum type (§8.9), or a compile-time error occurs
java.lang.Class
в списке разрешённых типов отсутствует, точка.
Добавят в спецификацию разрешение использовать java.lang.Class
— допилят и компилятор и VM.
В какой конкретно байткод это будет транслироваться — дело десятое.
P.S. Class literals, хоть тот же String.class
, на уровне байткода вполне себе загружаются из пула констант.
Добавят в спецификацию разрешение использовать java.lang.Class — допилят и компилятор и VM.
В какой конкретно байткод это будет транслироваться — дело десятое.
По-моему, это утверждение слегка неосторожное. Складывается такое впечатление, что главное — это принять решение, а выполнимо ли оно с заданным качеством — «дело десятое»…
Мы с вами говорим об одном и том же, только по разному.
Нет, ваша позиция — «Это очень сложно, потому и не сделали», моя — «Руки не дошли, вот и не сделали».
В пользу моей точки зрения говорит JDK-8213076 Pattern matching for switch, который как раз и посвящён добавлению этой возможности в язык, а вовсе не объяснению того, что это слишком сложно сделать.
Им и со строками-то уже сильно выворачиваться пришлось.
Сомневаюсь, что реализация вызвала сколь-нибудь серьёзные трудности. Принять решение — да, пришлось.
Складывается такое впечатление, что главное — это принять решение, а выполнимо ли оно с заданным качеством — «дело десятое»…
Не нужно передёргивать, я говорил про байткод. На уровне байткода этот switch
вполне может выродиться в пару invokedynamic
/tableswitch
, которые JIT заменит на intrinsics.
Синтаксический сахар это совсем не космические технологии.
Вам осталось сделать крошечный шаг до осознания того, что String.class как раз и является постоянной.
С чего бы? Я могу один и тот же класс грузить разными class loader'ми и это будут разные объекты.
Про continue/break и varargs знал, а вот про assert — нет. Если честно, вообще не помню, когда я последний раз видел assert в коде
this_is_for_loop:
for (int i = 0; i < 10; i++) {
print_variable_i:
System.out.println(i);
}
Кстати, IntelliJ IDEA умеет переписать за вас свитч по классам. Так что смело свитчуйтесь по любым объектам, IDEA всё поправит:
Результат:
if (String.class.equals(clazz)) {
return "str";
} else if (Integer.class.equals(clazz)) {
return "int";
}
return "obj";
Вещи, которые вы [возможно] не знали о Java