несовместимые типы: int нельзя преобразовать в логическое значение
Меня интересует, почему C это позволяет, а java нет. Поэтому меня интересует система типов языка, особенно его сильные стороны.
Ваш вопрос состоит из двух частей:
Почему Java не конвертируется int
в boolean
?
Это сводится к тому, что Java должна быть максимально явной. Это очень статично, очень "в вашем лице" с его системой типов. Вещи, которые автоматически приводятся в других языках, не таковы в Java. Вы также должны написать int a=(int)0.5
. Преобразование float
в int
потеряет информацию; такой же, как преобразование int
в boolean
и, таким образом, будет подвержен ошибкам. Также им пришлось бы указывать много комбинаций. Конечно, эти вещи кажутся очевидными, но они намеревались ошибиться на стороне осторожности.
Да, и по сравнению с другими языками Java была чрезвычайно точна в своей спецификации, поскольку байт-код был не просто внутренней деталью реализации. Они должны были бы точно указать любое и все взаимодействия. Огромное начинание.
Почему if
не принимает другие типы, чем boolean
?
if
вполне может быть определено, чтобы разрешить другие типы, чем boolean
. У этого может быть определение, которое говорит, что следующее эквивалентно:
true
int != 0
String
с .length>0
- Любая другая ссылка на объект, которая не является
null
(и не имеет Boolean
значения false
).
- Или даже: любая другая ссылка на объект, которая не является
null
и чей метод Object.check_if
(изобретенный мной только для этого случая) возвращает true
.
Они не сделали; в этом не было особой необходимости, и они хотели, чтобы он был как можно более надежным, статичным, прозрачным, легко читаемым и т. д. Нет явных особенностей. Кроме того, реализация будет довольно сложной, я уверен, что придется проверять каждое значение для всех возможных случаев, так что производительность могла также сыграть небольшую роль (Java раньше была запутанной на компьютерах того времени; не было JIT-компиляторов с первыми выпусками, по крайней мере, не на компьютерах, которые я использовал тогда).
Более глубокая причина
Более глубокая причина вполне может заключаться в том, что у Java есть свои примитивные типы, поэтому ее система типов разрывается между объектами и примитивами. Возможно, если бы они избежали этого, все могло бы сложиться иначе. С помощью правил, приведенных в предыдущем разделе, они должны были бы точно определять истинность каждого отдельного примитива (поскольку примитивы не разделяют суперкласс, и null
для примитивов нет четкого определения ). Это быстро превратилось бы в кошмар.
прогноз
Ну, и, в конце концов, может быть, это просто предпочтение языковых дизайнеров. Кажется, каждый язык крутится по-своему ...
Например, в Ruby нет примитивных типов. Все, буквально все, является объектом. Им очень легко убедиться, что у каждого объекта есть определенный метод.
Ruby ищет правдивость на всех типах объектов, которые вы можете бросить в него. Интересно, что у него все еще нет boolean
типа (потому что у него нет примитивов), и у него тоже нет Boolean
класса. Если вы спросите, какой класс true
имеет значение (доступно с помощью true.class
), вы получите TrueClass
. Этот класс на самом деле имеет методы, а именно 4 оператора для booleans ( | & ^ ==
). Здесь, if
считает его значение фальси тогда и только тогда, когда оно равно false
или nil
(the null
Ruby). Все остальное правда. Так что, 0
или ""
оба правда.
Для них было бы тривиально создать метод, Object#truthy?
который можно было бы реализовать для любого класса и вернуть индивидуальную правдивость. Например, String#truthy?
мог быть реализован, чтобы быть верным для непустых строк, или еще много чего. Они этого не сделали, хотя Ruby является противоположностью Java в большинстве отделов (динамическая типизация утки с миксином, повторное открытие классов и все такое).
Что может удивить программиста на Perl, который привык $value <> 0 || length($value)>0 || defined($value)
быть правдивым. И так далее.
Введите SQL с его соглашением, что null
внутри любого выражения автоматически делает его ложным, несмотря ни на что. Так (null==null) = false
. В рубине (nil==nil) = true
. Счастливые времена.