Почему Кастинг не транзитивный [дубликат]

На мобильных устройствах (с Chrome для Android или Opera Mobile) вы можете обнаружить увеличение по окну. visualViewport.scale. https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API

Обнаружение в Safari: document.documentElement.clientWidth / window.innerWidth (return 1, если нет масштабирования на устройстве).

4
задан Charlie 13 December 2014 в 15:18
поделиться

3 ответа

Когда вы объявляете объект Object a = 1.5, вы можете проверить, проверив System.out.println(a.getClass()), что объект фактически передан экземпляру Double. Это может быть снова добавлено к double из-за соглашений о распаковке. После этого значение double может быть передано в int.

Однако не существует соглашений о распаковке, выполняемых из экземпляра Double в файл int, поэтому среда выполнения выдаст ClassCastException если вы попытаетесь это сделать. Он не может напрямую перейти от Double к Integer.

3
ответ дан Maarten Bodewes 23 August 2018 в 00:06
поделиться
  • 1
    Надеюсь, что у вас все в порядке с моими изменениями, откиньтесь назад, если вы не согласитесь. – Maarten Bodewes 13 December 2014 в 15:35

Когда вы выполняете кастинг из Object, вы распаковываете из типа обертки ... и в основном вы можете удалить только исходный тип. Фактически это относится к соответствующему типу-оболочке, а затем к вызову соответствующего метода xxxValue. Таким образом, это:

Object x = ...;
double d = (double) x;

эквивалентно:

Object x = ...;
double d = ((Double) x).doubleValue();

То, что приведение к Double, очевидно, завершится ошибкой, если x не является ссылкой на Double .

Итак, ваш проблемный код эквивалентен:

Object a = Double.valueOf(1.5); // Auto-boxing in the original code
int b = ((Integer) a).intValue(); // Unboxing in the original code
System.out.println(b);

. Надеюсь, теперь понятно, почему это произойдет, потому что первая строка создает Double, который вы пытаетесь для перевода на Integer.

3
ответ дан Jon Skeet 23 August 2018 в 00:06
поделиться

Я не знаю, почему ваш код работает вообще. Вы не должны использовать Object для «double», потому что это несовместимые типы. Кроме того, тип литья int double является несовместимым. Ваш первый блок кода:

double a=1.5;
int b=(int)a;
System.out.println(b);

напечатает «1». Вы потеряете десятичные знаки. Если вы хотите просто напечатать номер до десятичной точки, тогда вы можете форматировать свой двойной при печати, и вам не нужно будет указывать тип int.

Но причина, по которой другие не работают, - это то, что вы пытаетесь использовать несовместимый тип. Странно, что вы говорите последние два блока кода

Object a=1.5;
double b=(double)a;
int c=(int)b;
System.out.println(c);


Object a=1.5;
int b=(int)(double)a;
System.out.println(b);

Они не должны работать из-за несовместимых типов.

1
ответ дан ngrant 23 August 2018 в 00:06
поделиться
  • 1
    Они не должны работать, и я знаю, что я должен использовать Double.parseDouble(a.toString()), но по какой-то причине это работает. – Charlie 13 December 2014 в 15:40
  • 2
    Я не уверен, как вы можете заставить это работать, но только ваш первый блок кода будет вызывать ошибку java несовместимых типов при компиляции. Поэтому кажется странным, что вы можете даже запустить их. – ngrant 13 December 2014 в 15:45
  • 3
    Я использую Java 8, и у меня нет никаких ошибок вообще – Charlie 13 December 2014 в 15:45
  • 4
    Как вы компилируете свой код? Предполагаю, что вы используете IDE, а не в командной строке? Я просто тестировал каждый блок в Java 7 & amp; 8 в Intelij, и это не позволит мне скомпилировать другой, чем первый блок. Например. public class Casting { public static void main(String args[]) { Object a=1.5; int b=(int)(double)a; System.out.println(b); } } вы настроили свою среду IDE, чтобы игнорировать предупреждения? – ngrant 13 December 2014 в 15:50
  • 5
    Я использую Eclipse, полный код здесь: pastebin.com/bRUVnuLA . Компиляция через терминал дает следующий результат: pastebin.com/aV8B5S3w – Charlie 13 December 2014 в 15:52
Другие вопросы по тегам:

Похожие вопросы: