Хобрук: Ваш путь к мастерству в программировании

Проблема в примитивных классах-оболочках

почему бы не использовать == при сравнении примитивных классов-оболочек, таких как Long, Integer и т. д., почему они не работают.

public static void main(String[] args) {

        Number l = Integer.parseInt("30");
        Number l2 = Integer.parseInt("30");
        System.out.println(l == l2);        

        l = Integer.parseInt("3000");
        l2 = Integer.parseInt("3000");
        System.out.println(l == l2);
    }

почему в приведенном выше коде один результат истинный, а другой ложный???

30.03.2013

  • Какой класс Number? Я мог бы написать произвольный класс Number и заставить == работать так, как захочу, даже если это бессмысленно. 30.03.2013
  • @RobertHarvey: вот спецификация для Number . У вас может быть любой тип объекта Number, и это может быть любая из оболочек числовых примитивов. 30.03.2013

Ответы:


1

Рассмотрим этот случай:

 new Integer(30)==new Integer(30) 

На каждой стороне == у вас есть новый экземпляр, тогда левая и правая стороны являются разными объектами, и сравнение оценивается как ложное (поскольку оно проверяет идентичность экземпляра).

Случай с боксом более сложен, поскольку он зависит от Integer.valueOf, который уже кэширует значение для некоторых целых чисел с низким значением (по крайней мере, в диапазоне от -128 до 127, хотя реализации могут выбирать больший диапазон).

Эта проблема аналогична следующей, где равенство оценивается как true, даже если нам сказали, что мы должны сравнивать строки, используя equals.

String a = "foo";
String b = "foo";
System.out.println(a==b);
30.03.2013

2

Во-первых, предупреждение: вы не сравниваете значения; вы сравниваете адреса памяти.

Классы-оболочки по-прежнему являются полноценными объектами, и единственный способ проверить равенство объектов — использовать метод equals(). Если бы вы сравнивали с совместимым* примитивом, то автоматическая распаковка превратила бы Integer в int и выполнила бы проверку на равенство. Обратите внимание, что Number нельзя распаковать автоматически; вам нужно будет вызвать intValue()< /a> чтобы вернуть int.

Во-вторых, Integer.valueOf() будет кэшировать значения в диапазон байтов от -128 до 127. Любые два объекта Integer, созданные в этом диапазоне, будут разрешаться в один и тот же адрес памяти.

*: Любой из этих Number объектов должен стать int.

30.03.2013

3

Эти линии

Number l = Integer.parseInt("30");
Number l2 = Integer.parseInt("30");

преобразуются компилятором Java (автоматическая отправка) в

Number l = Integer.valueOf(Integer.parseInt("30"));
Number l2 = Integer.valueOf(Integer.parseInt("30"));

Integer.valueOf(int) API сообщает, что этот метод всегда будет кэшировать значения в диапазоне от -128 до 127 включительно. То есть за 30 возвращается один и тот же экземпляр Integer из кеша; для 3000 возвращаются два разных (новых) экземпляра Integer.

30.03.2013

4

Согласно спецификации Java язык Java спецификация

Если заключенное в рамку значение p равно true, false, byte или char в диапазоне от до , или int или короткое число от -128 до 127 (включительно), то пусть r1 и r2 будут результатами любые два боксирующих преобразования p. Всегда так, что r1 == r2.

19.06.2020
Новые материалы

Базовое руководство по переносу концепций обучения в глубокое обучение
Обзор По мере того, как машинное обучение становится все более мощным и продвинутым, модели, обеспечивающие эту расширенную возможность, становятся все больше и начинают требовать огромного..

C в C.R.U.D с использованием React-Redux
Если вы использовали React, возможно, вы знакомы с головной болью, связанной с обратным потоком данных. Передача состояния реквизитам от родительских компонентов к дочерним компонентам может..

5 обязательных элементов современного инструмента конвейера данных
В цифровом мире предприятия используют конвейеры данных для перемещения, преобразования и хранения огромных объемов данных. Эти конвейеры составляют основу бизнес-аналитики и играют..

Случай использования npm3 вместо npm2 для разработки библиотеки
Некоторое время назад я создал библиотеку на NodeJS, чтобы упростить рендеринг на стороне сервера и клиента. Он использует React и React Router для отображения соответствующего HTML на веб-сайте...

Локаджит, спасибо, что поделились этой точкой зрения.
Локаджит, спасибо, что поделились этой точкой зрения. «Вы становитесь сильными, поднимая других, а не опуская их». Мы все можем извлечь уроки из этой цитаты.

Как простая библиотека может повысить производительность вашего приложения React
Знакомство с Million.js Виртуальный DOM React не такой быстрый. Но мы не можем обойти это. Если мы хотим React, нам нужно его придерживаться, верно? Нет, есть альтернатива. Million —..

Мой процесс подачи заявки в Школе программного обеспечения и дизайна Тьюринга
Мой последний пост на Medium был в конце августа, и в нем я пообещал написать еще раз, рассказывая историю моего процесса подачи заявки в Школу программного обеспечения и дизайна Тьюринга ...