Почему целые числа не кэшируются в Java?

Только для проверки мы находимся на той же странице, у Вас есть три ситуации.

  1. вставка амперсанда в атрибут с помощью addAttribute

  2. вставка амперсанда в элемент с помощью addChild

  3. вставка амперсанда в элемент свойством, перегружающимся

, Это - несоответствие между 2 и 3, которому сбили с толку Вас. Почему addChild автоматически не выходит из амперсанда, тогда как добавление свойства к объекту и устанавливание его значения выходят из амперсанда автоматически?

На основе моих инстинктов, и поддержанный эта ошибка , это было преднамеренным проектным решением. Перегрузка свойства ($a-> d = 'Пять & Six';) предназначается, чтобы быть "амперсандами Escape для меня" способ сделать вещи. addChild метод предназначен, чтобы быть, "добавьте точно, что я говорю Вам добавлять" метод. Так, какой бы ни поведение, в котором Вы нуждаетесь, SimpleXML, может разместить Вас.

Скажем, у Вас была база данных текста, где всех амперсандов уже оставили. Автовыход не работал бы на Вас здесь. Это - то, где Вы использовали бы addChild. Или позволяет, говорят, что необходимо было вставить объект в документ

$a = simplexml_load_string('');
$a->b = 'This is a non-breaking space  ';
$a->addChild('c','This is a non-breaking space  ');    
print $a->asXML();

, Это - то, что защищает разработчик PHP в той ошибке. Поведение addChild предназначено для обеспечения "менее простой, больше устойчивой" поддержки, когда необходимо вставить амперсанд в документ без него оставляемый.

, Конечно, это действительно оставляет нас с первой ситуацией, которую я упомянул, addAttribute метод. addAttribute метод делает амперсанды Escape. Так, мы могли бы теперь заявить несоответствие как [1 123]

  1. , addAttribute метод выходит из амперсандов
  2. , addChild метод не делает амперсанды Escape
  3. , Это поведение несколько непоследовательно. Разумно, что пользователь ожидал бы эти методы на SimpleXML выходить из вещей последовательным способом

, Это затем выставляет настоящую проблему с SimpleXML api. Идеальная ситуация здесь была бы

  1. , Свойство, Перегружающееся на Объектах Элемента, выходит из амперсандов
  2. , Свойство, Перегружающееся на Объектах Атрибута, выходит из амперсандов
  3. , addChild метод не выходит из амперсандов
  4. , addAttribute метод не выходит из амперсандов

, Это невозможно, хотя, потому что SimpleXML не имеет никакого понятия Объекта Атрибута. addAttribute метод (кажется?) единственный способ добавить атрибут. Из-за этого это складывается (кажется?) SimpleXML в неспособном из создания атрибутов с объектами.

Все это показывает парадокс [1 135] Простой XML. Идея позади этого API состояла в том, чтобы предоставить простому способу взаимодействовать с чем-то, что оказывается сложным.

команда, возможно, добавила Объект SimpleXMLAttribute, но это - добавленный слой сложности. Если Вы хотите несколько иерархия объектов, используйте DomDoument.

команда, возможно, добавила флаги к addAttribute и addChild методам, но флаги делают API более сложным.

реальный урок здесь? Возможно, это настолько просто, твердо, и прост на крайнем сроке, еще более твердо. Я не знаю, имело ли это место или нет, но с SimpleXML кажется, что кто-то запустил с простой идеи (используйте свойство, перегружающееся для создания создания XML-документов легким), и затем скорректированный, поскольку проблемы/запросы новых функций вошли.

На самом деле, я думаю, что реальный урок здесь должен просто использовать JSON ;)

25
задан Community 23 May 2017 в 12:00
поделиться

6 ответов

Это потому, что вы используете оператор new для создания объектов.

Integer a = Integer.valueOf(10);
Integer b = Integer.valueOf(10);
System.out.println("a == b: " + (a == b));

Это распечатает true. Странно, но на Яве.

-1
ответ дан 28 November 2019 в 21:15
поделиться

Позвольте мне немного подробнее остановиться на ответах ChrisJ и EboMike, дав ссылки на соответствующие разделы JLS.

new - это ключевое слово в Java, разрешенное в выражениях создания экземпляров класса ( Раздел 15.9 JLS ). Это отличается от C ++, где new является оператором и может быть перегружен.

Выражение всегда пытается выделить память и выдает новый объект каждый раз, когда он оценивается ( Раздел 15.9.4 ). Так что на данный момент уже слишком поздно для поиска в кэше.

1
ответ дан 28 November 2019 в 21:15
поделиться

new означает new.

new Object() не легкомысленно.

1
ответ дан 28 November 2019 в 21:15
поделиться

Разве не было бы больше смысла, если бы все экземпляры целого числа с 10 были одним и тем же объектом в памяти? Другими словами, почему у нас нет "Integer interning", который похож на "String interning"?

Потому что это было бы ужасно!

Во-первых, этот код будет бросать OutOfMemoryError:

for (int i = 0; i <= Integer.MAX_VALUE; i++) {
    System.out.printf("%d\n", i);
}

Большинство целочисленных объектов, вероятно, недолговечны.

Во-вторых, как бы вы поддерживали такой набор канонических целочисленных объектов? С какой-то таблицей или картой. И как бы вы судили доступ к этой карте? С какой-то блокировкой. Так что внезапно автобокс стал бы кошмаром синхронизации производительности, убивающей производительность для многопоточного кода.

2
ответ дан 28 November 2019 в 21:15
поделиться

Для Integer объектов используйте условие a.equals(b) для сравнения.

Компилятор не будет распаковывать вас во время сравнения, если вы не назначите значение базовому типу.

0
ответ дан 28 November 2019 в 21:15
поделиться

В Java каждый раз, когда вы вызываете оператор new, вы выделяете новую память и создаете новый объект . Это стандартное поведение языка, и, насколько мне известно, нет способа обойти это поведение. Даже стандартные классы должны соблюдать это правило.

2
ответ дан 28 November 2019 в 21:15
поделиться
Другие вопросы по тегам:

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