LINUX.ORG.RU

Java факап

 , ,


0

1

Что вернёт метод и почему?

public int x() {
  boolean isFalse = false;
  Integer i1 = 1;
  String str = "x";
  if (str.equals("e") && 
      !isFalse ? true : i1.equals(1)) {
    return 1;
  }
  return 0;
}
//openjdk version "1.8.0_222"

★★★★★

Последнее исправление: crutch_master (всего исправлений: 3)

Детский сад. Задачка уровня «сколько WTF в этом индусском коде».

Т. е. определённый академический интерес усмотреть можно.

Но никто в здравом уме не делает боксинг примитивного целого с тем, чтобы потом вызвать на нём equals().

И в серьёзном проекте за такой стиль кода надо гнать тряпками.

Bass ★★★★★
()
Ответ на: комментарий от crutch_master

Выдаст 1. Тернарный оператор распарсит всю левую часть как одно выражение, которое вычислится в false, поэтому управление перейдет на i1.equals(1), который вычислится в true.

Код – говно, а тернарный оператор – одна из худших фич С-подобных языков, сразу после оператора ,.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от Siborgium

Код – говно, а тернарный оператор – одна из худших фич С-подобных языков

Нормальный тернарный оператор, а код, да, говно.

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от mimico

Потому что его функции должно выполнять выражение if-else, которое, к сожалению, в С-подобных языках выражением не является, а является блоком. Подобной ошибки не возникло бы, так как программист был бы вынужден явно расставить скобки.

if (if (str.equals("e") && !isFalse) { true } else { i1.equals(1) }) {
    // . . .
} else {
    // . . .
}

Так мог бы выглядеть этот код, будь язык сделан чуть более по-человечески. Не говоря уже о том, что его можно переписать более читаемо через промежуточные выражения или хотя бы логические операторы.

Siborgium ★★★★★
()
Ответ на: комментарий от crutch_master

Вот никогда не понимал этого. Логично ожидать определенного приоритета арифметических операторов, но всех остальных, как можно как-то особенно ожидать. На основании какой такой логики.

mimico
()
Последнее исправление: mimico (всего исправлений: 1)
Ответ на: комментарий от Siborgium

Так условие с тернарным оператором тоже можно заключить в скобки.

Правильно я понимаю, что плохой он, потому что не вынуждает расставлять скобки?

mimico
()
Ответ на: комментарий от mimico

Почему?

Потому что код пишут один раз, одним человеком. А читают его потом много раз, тысячами человеков. И нужно убивать за код, представленный выше, потому что он отнимает десятки тысяч человеко часов на парсинг этого дерьмища. Вывод - код должен легко читаться и легко парситься, тогда ты сэкономишь людям время, которое они всё равно сольют в никуда, но это уже другая история.

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от foror

Так он не правильный и уже отнял 1.5 человекодня на расследование, еще до того, как я его прочитал. Я хз, как до этого всё работало.

crutch_master ★★★★★
() автор топика
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от mimico

Если вкратце – да. Если не вкратце, то уже то, что он является оператором, буквально провоцирует такие ошибки.

Можно пойти по пути Раста (на самом деле, любого языка из ML-семьи) и сделать все конструкции выражениями. Не нужно будет специального синтаксиса для if-else и для if-else-выражения.

Можно пойти по пути Паскаля и не иметь выражений, меняющих control flow. Тогда юзер будет вынужден отдельно расписать свое условие и подставить результат в if-else блок.

C, C++, C#, Java и подобные пытаются усидеть и там, и там, создавая вот такие проблемы.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Если не вкратце, то уже то, что он является оператором, буквально провоцирует такие ошибки

Эм, но ведь тернарный оператор легко заменяется комбинацей логических or / and операторов. Их тоже быть не должно?

mimico
()
Ответ на: комментарий от crutch_master

Ожидалось, что у ? выше приоритет, чем у &&

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

gedisdone ★★★
()
Ответ на: комментарий от mimico

но ведь тернарный оператор легко заменяется комбинацей логических or / and операторов

Это на js так можно. На яве логические вернут только true/false.

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от mimico

Да, заменяется. Но применение логических операторов для изменения control flow куда менее распространено и гораздо легче отлавливается линтерами и анализаторами.

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

Siborgium ★★★★★
()
Ответ на: комментарий от crutch_master

Это всё равно, что заменив «a + c*4» на «a + c<<2» удивляться изменившемуся результату.

monk ★★★★★
()

о чём вообще спор? Это проблемы вимеров?

В нормальной IDE есть проверки, и на такой код плагины ругаются, и подчёркивают всё.

fsb4000 ★★★★★
()
Ответ на: комментарий от crutch_master

Ну вот, всю интригу сломал.

Подожди, т.е. это правильный ответ? Не будет никаких WTF в стиле рубей и джаваскрипта? В чем тогда проблема, если все логично вычисляется?

Im_not_a_robot ★★★★★
()
Ответ на: комментарий от crutch_master

Мне кажется, тут перенос строки в неудачном месте. Что касается приоритетов операций, то их нужно просто знать. Я пытался в Яре уменьшить их количество по сравнению с Си, где их, ЕМНИП, больше 10, но в любом ЯП много всего намешано, и почему-то таблицу приоритетов особо сильно не ужмёшь. Как методически решить эту проблему - я не знаю. Хоть я и не любитель Си, но тут, мне кажется проблема скорее в том, что в данном проекте ?: применялся редко, и автор просто запамятовал и ошибся, а в худшем случае просто не знал. Подобные вещи неизбежны.

Вариант, когда if возвращает значение, выглядит осмысленным - становится на один оператор меньше. Но увеличивается в целом сложность чтения кода - больше нужно держать в голове, чтобы, прочитав весь этот if, потом вернуться к точке вызова и вставить результат куда надо. Для маленьких if-ов это будет хорошо работать, для больших - плохо.

den73 ★★★★★
()
Ответ на: комментарий от Siborgium

а тернарный оператор – одна из худших фич С-подобных языков

Не надо гнать! Очень удобная вещь. Просто в ОП эталонный пример того, как НЕ надо её применять.

hobbit ★★★★★
()
Ответ на: комментарий от den73

Мне кажется, тут перенос строки в неудачном месте.

Нет, нет, как раз таки он в самом удачном месте:)

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от fsb4000

Ну понятно, потому что тут всё определенно. В реальном коде там параметры метода и итераторы каких-то циклов.

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от Im_not_a_robot

В чем тогда проблема, если все логично вычисляется?

Ни в чём. Тут обсуждают, какой этот тернарный оператор не нужный.

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от hobbit

Научиться применять оператор, запомнить его приоритет – не проблема, вопрос 15 минут, если не меньше. Но код-то не только пишется, он еще и читается. Кроме того, он может писаться кем-то еще, а читаться очень даже тобой.

Тернарный оператор затрудняет как чтение, так и парсинг кода, приводит к таким ошибкам.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от mimico

Ни капли не перекладываю вину на инструмент. Виноват написавший этот код. Сделал он это по невнимательности, или не знал о приоритете оператора – неважно, виноват в ошибке он. Речь я веду о том, что будь инструмент другим – этого бы не произошло.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Чтобы не было ошибок инструмент должен быть таким, чтобы на нём ничего нельзя было сделать.

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от den73

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

Это – хороший аргумент. Все так, это заметно уже на том куске кода, который я привел. Но, по крайней мере, не будет такого треша как в оппосте.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Тернарный оператор затрудняет как чтение, так и парсинг кода, приводит к таким ошибкам.

Кодер, который вкорячил тернарный оператор в if, найдет еще десяток способов расставить мины. Операторы это вообще сложна: закорючки какие-то, правила расстановки которых нужно зубрить. Ответ на эти потуги один: лисп!

bread
()
Ответ на: комментарий от winlook38

Что вернули юнит-тесты и почему?

Какие юнит тесты?

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от crutch_master

Но тернарный оператор там остался :)

anonymous
()
Ответ на: комментарий от crutch_master

Нет никакой интриги. С незапамятных времен известно, что приоритет неарифметики легко попутать, и поэтому ты либо охрененно уверен в себе, либо ставишь скобки до тех пор, пока не станешь уверен.

anonymous
()
Ответ на: комментарий от foror

код должен легко читаться и легко парситься, тогда ты сэкономишь людям время Java факап (комментарий)

Да, офигеть как легко парсится, вместо простого тернарника, которому надо только скобок поставить в условии.

anonymous
()
Ответ на: комментарий от mimico

Да, потому что в школе годами учат его парсить. А про тернарный оператор максимум вскользь скажут.

t184256 ★★★★★
()
Последнее исправление: t184256 (всего исправлений: 1)
Ответ на: комментарий от Siborgium

Можно еще на интервью спрашивать дельные вещи вроде того, как работать с приоритетами, вместо несусветной х^иты уровня «реализуй тредсейфный локфри мап руками на вайтборде». А потом сидят формы шлепают без скобок вокруг тернарника.

anonymous
()

Судя по всему удивление вызвано тем, что ты не знал, что у тернарников низкий приоритет?

ya-betmen ★★★★★
()
Ответ на: комментарий от Siborgium

Научиться применять оператор, запомнить его приоритет – не проблема, вопрос 15 минут

Хахаха. Размазанных по месяцу разве что. Раз показать, задачку, втф как в сабже, проверочную, разбор, проверочную, разбор, проверочную, разбор — и вот уже 75% будут внимательным на 100%. Период полураспада знаний — ~год, дальше продолжать?

t184256 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.