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);
    }
}