Почему Ваш тип данных оператора переключения не может быть долгим, Java?

Вот выборка из учебных руководств по Java Sun:

Переключатель работает с byte, short, char, и int примитивные типы данных. Это также работает с перечислимыми типами (обсужденный в Классах и Наследовании) и нескольких специальных классах, которые "переносят" определенные типы примитивов: Character, Byte, Short, и Integer (обсужденный в простых объектах данных).

Должно быть серьезное основание почему long примитивный тип данных не позволяется. Кто-либо знает, каково это?

74
задан Nayuki 27 July 2017 в 06:23
поделиться

4 ответа

Я думаю, что некоторые насколько это вероятно было произвольное решение, основанное на типичном использовании переключателя.

Переключатель по существу может быть реализован двумя способами (или, в принципе, комбинацией): для небольшого количества случаев или тех, чьи значения сильно различаются, переключатель по существу становится эквивалентом серии ifs на временном переменная (включаемое значение должно быть оценено только один раз). Для умеренного количества случаев, которые являются более или менее последовательными по значению, используется таблица переключения (инструкция TABLESWITCH в Java), посредством чего место перехода эффективно ищется в таблице.

Любой из этих методов в принципе может использовать длинное значение, а не целое число. Но я думаю, что это было, вероятно, просто практическое решение сбалансировать сложность набора инструкций и компилятора с реальной потребностью: случаи, когда вам действительно нужно переключаться на долгое время, достаточно редки, и их можно переписать как серию операторов IF или обойтись каким-либо другим способом (если рассматриваемые длинные значения близки друг к другу, вы можете в своем коде Java переключить результат int вычитания наименьшего значения).

47
ответ дан 24 November 2019 в 12:05
поделиться

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

[РЕДАКТИРОВАТЬ: извлечено из комментариев к этому ответу, с некоторыми фоновыми дополнениями]

Если быть точным, 2³² - это много случаев, и любая программа с методом, достаточно длинным, чтобы вместить больше этого, будет просто ужасной! На любом языке. (Самая длинная функция, которую я знаю в любом коде на любом языке, чуть больше 6k SLOC - да, это большой переключатель - и он действительно неуправляем.) Если вы действительно застряли с ] long , где у вас должно быть только int или меньше, тогда у вас есть две реальные альтернативы.

  1. Используйте какой-нибудь вариант на тему хеш-функций, чтобы сжать long в int . Самый простой способ, который можно использовать только тогда, когда у вас неправильный тип, - это просто приведение! Более полезным было бы сделать это:

     (int) ((x & 0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF)) 
     

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

  2. Гораздо лучшим решением, если вы работаете с очень большим количеством кейсов, является изменение вашего дизайна на использование Map или чего-то подобного, чтобы вы узнали, как отправить определенное значение.Это позволяет вам разделить дела на несколько файлов, что намного проще контролировать, когда количество дел становится большим, хотя становится сложнее организовать регистрацию хоста задействованных классов реализации (аннотации могут помочь, позволяя вам создать регистрационный код автоматически).

    FWIW, я сделал это много лет назад (мы перешли на недавно выпущенный J2SE 1.2 в ходе реализации проекта) при создании собственного механизма байт-кода для моделирования массивно параллельного оборудования (нет, повторное использование JVM было бы неприемлемым из-за к радикально отличающимся моделям значений и исполнения), и это значительно упростило код по сравнению с большим переключателем , который использовала версия кода на языке C.

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

19
ответ дан 24 November 2019 в 12:05
поделиться

Потому что индекс таблицы поиска должен быть 32 бита.

4
ответ дан 24 November 2019 в 12:05
поделиться

Long в 32-битных архитектурах представлен двумя словами . Теперь представьте, что могло бы случиться, если бы из-за недостаточной синхронизации выполнение оператора switch наблюдало бы long с его старшими 32 битами от одной записи, а 32 младшими - с другой! Он мог бы попытаться попасть в .... неизвестно куда! В основном где-то наугад. Даже если обе записи представляют допустимые случаи для оператора switch, их забавная комбинация, вероятно, не приведет ни к первому, ни ко второму - или, что еще хуже, это может привести к другому допустимому, но не связанному с ним случаю!

По крайней мере, с int (или меньшими типами), независимо от того, насколько сильно вы ошиблись, оператор switch по крайней мере прочитает значение, которое кто-то на самом деле написал , вместо значения "из тонкого" воздух".

Я, конечно, не знаю истинной причины (прошло уже более 15 лет, я так давно не обращал внимания!), Но если вы понимаете, насколько небезопасной и непредсказуемой может быть такая конструкция, вы » Я согласен с тем, что это определенно очень веская причина , чтобы никогда не включать longs (и, как и предполагалось, long -pun - будут 32-битные машины, эта причина останется в силе) .

-10
ответ дан 24 November 2019 в 12:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: