... Czy to dlatego, zmienne lokalne są alokowane na stosie, a więc mój nowy jest zszokowana, gdy Opuszczam tę metodę?
Nie. Jest to spowodowane argumentem przechodzącym do semantyki języka Java.
Argumenty Java są przekazywane "według wartości", ale w przypadku typu obiektu lub tablicy wartość, którą przekazujesz, jest odniesieniem do obiektu/tablicy. Podczas tworzenia i przypisywania nowego obiektu zestawu do mySet
, wystarczy ustawić lokalną zmienną/parametr. Ponieważ Java używa wartości przekazywanych według wartości, nie ma to wpływu na zmienną foo
w metodzie main
.
Po wprowadzeniu metody test
masz dwie kopie odwołania do instancji HashSet
utworzonej w metodzie main
; jeden w foo
i jeden w mySet
. Twój kod następnie zastępuje odniesienie w mySet
z odniesieniem do nowo utworzonego HashSet
, ale ten nowy odnośnik nie zostanie przekazany z powrotem do osoby dzwoniącej. (Można zmienić swój kod, aby przenieść go z powrotem ... na przykład w wyniku metody test
Ale trzeba to zrobić w sposób jawny.).
OK - jednak - jeśli miałbym zrobić add lub inna operacja w ramach wywołania metody, ta alokacja zostanie zachowana. Dlaczego?
To dlatego, że podczas wywoływania metody instancji przy użyciu odniesienia w foo
lub mySet
, że metoda jest wykonywana na obiekcie (HashSet
), że wniosek dotyczy. Zakładając, że te dwa odniesienia wskazują na ten sam obiekt, twój "przydział zostanie zachowany". A dokładniej, możesz obserwować efekty operacji na jednym odnośniku do obiektu poprzez operacje na innych odniesieniach do tego samego obiektu.
Pamiętaj tylko, że metoda Java wywołuje odwołania do obiektu, a nie same obiekty.
Przy okazji nie będzie można dodać elementów do zestawu zwróconego przez Collections.emptySet()
. Ten obiekt zbioru jest niezmienny.Wywołanie (na przykład) add
spowoduje zgłoszenie wyjątku.
dzieła, jednak - gdybym nie dodawać lub jakaś inna operacja w ciągu moje wywołanie metody, ta alokacja zostanie zachowana. Dlaczego? –
Doskonała odpowiedź Stephen, dziękuję. –