... Это потому, что локальные переменные размещены в стеке, и поэтому мой новый сдувается, когда я выхожу из метода?
Нет. Это из-за семантики передачи аргументов Java.
Аргументы Java передаются "по значению", но в случае типа объекта или массива значение, которое вы передаете, является ссылкой на объект/массив. Когда вы создаете и назначаете новый объект набора mySet
, вы просто устанавливаете локальную переменную/параметр. Поскольку Java использует передачу по значению, это не влияет на переменную foo
в методе main
.
Когда вы вводите метод test
, у вас есть две копии ссылки на экземпляр HashSet
, созданный в методе main
; один в foo
и один в mySet
. Затем ваш код заменяет ссылку в mySet
ссылкой на вновь созданный HashSet
, но эта новая ссылка не передается обратно вызывающей стороне. (Вы можете изменить свой код, чтобы передать его обратно... например, как результат метода test
. Но вы должны сделать это явно.)
ОК, однако, если бы я выполнил операцию добавления или какую-либо другую операцию в вызове моего метода, это распределение было бы сохранено. Почему это?
Это связано с тем, что когда вы вызываете метод экземпляра, используя ссылку в foo
или mySet
, этот метод выполняется для объекта (HashSet
), на который ссылается ссылка. Предполагая, что две ссылки указывают на один и тот же объект, ваше «распределение будет сохранено». Или, точнее, вы можете наблюдать за эффектами операций над одной ссылкой на объект через операции над другими ссылками на тот же объект.
Просто помните, что метод Java вызывает копирование ссылок на объект, а не на сами объекты.
Кстати, вы не сможете добавлять элементы в набор, возвращаемый Collections.emptySet()
. Этот заданный объект является неизменным. Вызов (например) add
вызовет исключение.
person
Stephen C
schedule
20.07.2010