Подтвердить что ты не робот

Почему Java не разрешает кастинг Boolean → Int?

Мне было интересно, почему Java не разрешает кастинг от булева до int, например:

boolean foo = true;
int bar = (int)foo;

Это можно сделать в одной строке кода, например,

bar = foo ? 1 : 0;

но кажется, что лучше и проще для чтения было бы разрешить литье типов, как с double и int. Почему Java не включает эту функцию?

4b9b3361

Ответ 1

Это не позволяет этого, потому что разработчики Java (правильно) признали, что перегрузка логическими/целыми числами в C и C++ была значительным источником ошибок.

(Я помню, что видел это в письменном виде в каком-то обосновании дизайна, но не могу его найти.)

Например:

if (i = 0) {
    ...
}

допустимо, но, вероятно, ошибка в приложении, которое написано C или C++.

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

Это работает не во всех случаях. Например (на Java):

if (flag = true) {
    ...
}

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

if (flag) {
    ...
}

который полностью избегает ловушки. Кроме того, проверка, такая как findbugs или pmd должна pmd неверную версию как подозрительную.


Теперь это не объясняет, почему вы не можете явно вводить тип boolean для int. Но я думаю, что это можно понять, соблюдая следующее:

  • Вам редко нужно делать это в реальных программах Java.

  • Булево приведение чисел <-> не помешает работе других типов. В частности, для других типов есть приведения и приведения, а приведения 1 в Java не требуют явного приведения типа.

  • Вы не можете типизировать между числами и строками либо между строками и другими объектами. Это преобразования, а не приведение типов. И int <-> тоже boolean.


1 - Я не совсем согласен с моей терминологией (намеренно).Правильная терминология Java - "расширение" и "сужение".Сужающие преобразования требуют явного приведения типов с ограниченным исключением для литералов.Расширяющиеся преобразования не требуют приведения типов.

Ответ 2

Java поддерживает расширение конверсий на примитивных числовых типах. Однако логическое значение не считается числовым.

Поддерживаемые расширяющиеся преобразования перечислены в "Расширение примитивного преобразования" в Спецификации языка Java.

Ответ 3

Поскольку Java строго типизирован, boolean и int are two completely different data types, и нельзя отличить его от другого - на самом деле его нельзя отличить.