Java: много способов сбрасывать (длинный) объект на двойной
У меня есть Object obj
, который, как я знаю, на самом деле является long
.
В каком-то математическом коде мне это нужно как double
.
Безопасно ли сразу его дублировать в два раза?
double x = (double)obj;
Или я должен скорее перенести его сначала на длинный, а затем на двойной.
double x = (double)(long)obj;
Я также нашел другую (менее читаемую) альтернативу:
double x = new Long((long)obj).doubleValue();
Каковы опасности/последствия этого?
Резюме решения:
-
obj
является Number
, а не a long
.
- Java 6 требует явного литья, например:
double x = ((Number)obj).doubleValue()
- В Java 7 работает магия:
double x = (long)obj
Подробнее о проблеме Java6/7 также читайте обсуждение ответа TJ.
Изменить: Я провел несколько быстрых тестов. Оба способа каста (явный/магический) имеют одинаковую производительность.
Ответы
Ответ 1
Поскольку каждое примитивное число в Java получает свой тип бокса, когда требуется объект (в нашем случае Long
), и каждый номер в коробке является экземпляром Number
, самый безопасный способ для этого:
final Object object = 0xdeadbeefL;
final double d = ((Number)object).doubleValue();
Опасность здесь, как всегда, в том, что Object
, которую мы хотим использовать, не относится к типу Number
, и в этом случае вы получите ClassCastException
. Вы можете проверить тип объекта, например
if(object instanceof Number) ...
если вы хотите запретить исключения класса и вместо этого укажите значение по умолчанию, например 0.0
. Также бесшумные методы не всегда являются хорошей идеей.
Ответ 2
У меня есть Object obj
, который, как я знаю, на самом деле является long
.
Нет, нет. long
- примитивный тип данных, а примитивные типы в Java - это не объекты. Обратите внимание, что существует разница между примитивным типом long
и java.lang.Long
, который является классом-оболочкой.
Вы не можете наложить long
(объект) на long
(примитив). Чтобы получить значение long
из long
, вызовите longValue()
на нем:
Long obj = ...;
long value = obj.longValue();
Безопасно ли прямо передавать его на double
?
Если это на самом деле примитив long
, то да, вы можете применить его к double
. Если это объект long
, вам не нужно бросать его, вы можете просто называть его doubleValue()
:
double x = obj.doubleValue();
Ответ 3
Вам нужен только один отбор: от объекта до длинного или длинного (который неявно отбрасывает Long, а затем применяет распаковку):
Object o = 5L;
double d = (long) o; //Apparently only works on Java 7+
//or
double d = (Long) o;
Ответ 4
Простое литье должно работать отлично. Это будет быстрее, чем переход через классы-обертки, получение строкового представления, а затем синтаксический анализ в double, создание нового экземпляра снова с использованием длинного значения - и, что более важно, более читаемого.
double d = (double)15234451L;
Ответ 5
Вы можете направить его на Long
(так как Object
не a Long
, но Long
), а затем введите Long
в double
double d = (double)(Long)obj;
Например, у этого есть ожидаемый вывод 2.6666666666666665:
public class CastDouble {
public static final void main(String[] args) {
Object o = 15L;
System.out.println(40 / (double)(Long)o);
}
}