Почему у классов-оболочек для Примитивов нет сеттера? - PullRequest
4 голосов
/ 21 июля 2010

По какой причине классы Wrapper (такие как Integer, Double и т. Д.) Не имеют установщика для их внутреннего примитивного значения?

Я спрашиваю об этом, потому что такого рода функциональность упростила бы исчисление и сделала бы язык Java немного более гибким.

Позвольте привести несколько примеров.

1) Давайте рассмотрим следующий пример:

Integer x = new Integer(5);
x++;

Предыдущий скрытый код выполняет автобокс. Что-то вроде:

int x_tmp = x.intValue();
x_tmp++;
x = new Integer(x_tmp); // Yes that's a new memory allocation

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

2) Другая проблема, которая меня беспокоит, заключается в том, что в Java невозможно написать функцию подкачки, как я могу сделать в C (с помощью указателей) или в C ++ (указатели или ссылки). Если я напишу void swap(Integer x, Integer y), я не могу получить доступ к внутреннему значению, потому что, и я не смогу поменять значения.

PS: Мой друг предложил мне рассмотреть более широкую картину и подумать о параллелизме и неизменности типов.

Так у вас есть объяснение этому? Спасибо!

Ответы [ 4 ]

6 голосов
/ 21 июля 2010

Классы Wrapper обычно не используются, если вам не нужно поместить их в коллекцию.Если бы они были изменяемыми, это создавало бы проблемы при использовании внутри наборов и в качестве ключей для хеш-таблиц.

Для множеств и хеш-таблиц необходимо, чтобы значение хеш-функции всегда было одинаковым.

4 голосов
/ 21 июля 2010

Кэширование целых чисел в диапазоне от -128 до 127 требует неизменных целых чисел.Рассмотрим следующий код:

Integer id = Integer.valueOf(1);  // a new Integer, cached in Integer class

// and somewhere else

Integer key = Integer.valueOf(1);  // returns the cached value

Теперь , если Целочисленное значение было изменяемым и имело установщик, а кто-то сделал

key.setValue(2);  // not legal Java code, just for demonstration

, это изменит значение idтоже и, к удивлению многих народов:

Integer one = Integer.valueOf(1);
if (one != 1)
   System.out.println("Surprise! I know, you expected `1`, but ...");
4 голосов
/ 21 июля 2010

1) С установщиком типы оболочки будут изменяемыми. Неизменность - это хорошая вещь во многих отношениях ... многопоточность, общая понятность кода и т. Д. Лично я считаю, что позор, что Calendar и Date являются изменяемыми, например.

На самом деле, ваше расширение x++; не совсем правильно - оно использует Integer.valueOf, которое не всегда создает новое значение. Например:

Integer x = 5;
x++;
Integer y = 5;
y++;

// This prints true    
System.out.println(x == y); // Compare references

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

2) Да, у Java нет передачи по ссылке. Честно говоря, я очень редко нахожу это проблемой. Как часто вам действительно нужно менять значения переменных?

1 голос
/ 26 апреля 2013

В Java классы Strings и wrapper разработаны как неизменяемые, чтобы избежать случайных изменений данных. Вы можете проверить следующую статью для получения дополнительной информации.

Почему классы Strings и Wrapper неизменны в Java?

...