Если я использую тернарный оператор для присвоения переменной Object со значением Double или Integer, по какой-то причине она преобразуется в двойную.
Независимо от того, что я делаю с порядком и условием параметров тернарного оператора, по какой-то причине он все равно будет Double. Вот несколько примеров:
final Object n = false ? Double.parseDouble("2") : Integer.parseInt("1");
System.out.println(n + " " + n.getClass()); // Output is "1.0 class java.lang.Double"
final Object n = false ? Integer.parseInt("1") : Double.parseDouble("2");
System.out.println(n + " " + n.getClass()); // Output is "2.0 class java.lang.Double"
final Object n = true ? Integer.parseInt("1") : Double.parseDouble("2");
System.out.println(n + " " + n.getClass()); // Output is "1.0 class java.lang.Double"
final Object n = true ? Integer.valueOf("1") : Double.valueOf("2");
System.out.println(n + " " + n.getClass()); // Output is "1.0 class java.lang.Double"
Как вы можете видеть в последнем примере, я пытался использовать valueOf
вместо parse*
, который возвращает не примитивные типы (поэтому нет причин приводить их для присвоения переменной объекта???), но результат все равно будет тем же. Вопрос в том, почему значение приведения Java именно к Double, если оно определенно не зависит от порядка параметров, того, какие из них выбраны, и необходимости приведения?
double
сильнее int
, поэтому в бою победит первый. Это мое предположение, и мне не хотелось бы искать в спецификации языка, чтобы узнать, каковы на самом деле «правила» вышеизложенного. Декомпилируйте его и найдите инструкцию i2d
. valueOf
здесь, кстати, рациональный код
@ElliottFrisch: Нет, если бы это произошло, int был бы помещен в целое число и остался бы таким, вместо того, чтобы конвертироваться в Double. На самом деле это соответствует приведенному выше случаю: «В противном случае к типам операндов применяется двоичное числовое продвижение (§5.6.2), а тип условного выражения является расширенным типом второго и третьего операндов. Обратите внимание, что двоичное числовое продвижение выполняет преобразование распаковки (§5.1.8) и преобразование набора значений (§5.1.13)».
Этот вопрос похож на: Неожиданный тип, полученный в результате тернарного оператора. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.
Тип, возвращаемый условным оператором, определяется Спецификацией Java в зависимости от типов второго и третьего операндов.
В вашем первом и третьем случае второй операнд — это int
, третий — double
. Если вы посмотрите на Таблицу 15.25-Б. Тип условного выражения (3-й примитивный операнд, часть II) в связанной спецификации результат такой условной операции определяется как bnp(int,double)
, что означает, что оно применяет двоичное числовое продвижение результата int
к double
, который затем автоматически упаковывается в Double
, поскольку вы присваиваем результат Object
.
Во втором и четвертом случае у нас есть Integer
и Double
. Таблица 15.25-Д. Тип условного выражения (ссылка на 3-й операнд, часть II) сообщает нам, что тип возвращаемого значения — bnp(Integer,Double)
, поэтому, опять же, Double
.
В случае valueOf
второй и третий операнды имеют тип Integer
и Double
, а не int
и double
. Этот случай проходит несколько другую серию преобразований.
В разделе Таблица 15.25-С. Тип условного выражения (ссылка на 3-й операнд, часть I) мы видим, что если у нас есть второй параметр типа Double и третий — целое число, у нас должен быть bnp(Double,Integer), что означает, что в качестве результата мы должны получить целое число? Если да, пожалуйста, проверьте первый случай, где похоже, что он не работает.
В первом случае это двойной и int, а не Double
и Integer
, поэтому он возвращает double
, который затем автоматически упаковывается в Double
@FedericoklezCulloca Я заменил parse*
на valueOf
, чтобы получить Double
и Integer
, и результат остался тот же
Пожалуйста, вместо того, чтобы говорить «Я заменил», покажите полный пример и фактический результат, который вы получите.
@FedericoklezCulloca final Object n = true ? Double.valueOf("2") : Integer.valueOf("1"); System.out.println(n + " " + n.getClass()); // 2.0 class java.lang.Double
Опять 2-й — Double
, третий — Integer
, в результате получается bnp(Double,Integer)
, то есть Double
(imgur.com/a/BQ1UdAf)
bnp(Double, Integer) на самом деле имеет тип double, а не Double, но затем он автоматически упаковывается для присвоения объекту.
«поэтому нет причин приводить их к назначению объекта var» Что?
Object
не может хранить примитив. Примитивы всегда будут помещены в рамку, если вы присвоите их переменнойObject
.