Почему ваш тип данных оператора switch не может быть длинным, Java?

Здесь выдержка из Учебники Sun Java:

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

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

Ответ 1

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

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

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

Ответ 2

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

[EDIT: извлечено из комментариев по этому вопросу, с некоторыми дополнениями на фоне)

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

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

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

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

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

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

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

Ответ 3

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

Ответ 4

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

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

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