I_R_W13_M11_Java Struktury danych w Java
Referencje – pojęcie i zastosowanie
Wszystkie obiekty w języku Java są obsługiwane przez referencje. Nie należy ich jednak mylić ze wskaźnikami lub referencjami języka C++. Różnica polega na tym, że referencje w języku Java nie odnoszą się bezpośrednio do lokalizacji pamięci, ale zawierają wskaźnik do rzeczywistej lokalizacji pamięci, do której programista nie może uzyskać bezpośredniego dostępu. Ten dodatkowy poziom pośrednictwa jest wymagany m.in. do działania Garbage Collectora.
Przyjrzymy się definicji klasy o nazwie Osoba, która zawiera pole imie typu String służące do przechowywania imienia osoby. W głównej metodzie programu tworzony jest nowy obiekt klasy Osoba o nazwie znajomy, a do pola imie tego obiektu przypisywane jest imię „Artur”. Poprzez wykonanie tego kodu, tworzony jest obiekt reprezentujący osobę o imieniu „Artur”, co demonstruje podstawowe zastosowanie klas i obiektów w programowaniu obiektowym w języku Java.
Zwróć uwagę na słowo kluczowe new.
Słowo kluczowe new w języku Java służy do tworzenia nowych obiektów. Gdy go używamy, rezerwujemy pamięć na nowy obiekt na stercie (z j. ang. heap) i inicjalizujemy go zgodnie z definicją jego klasy. Ogólna składnia new wygląda następująco:
gdzie:
TypObiektuto nazwa klasy obiektu, który chcemy utworzyć;nazwaObiektuto nazwa zmiennej, która będzie przechowywać referencję do nowo utworzonego obiektu.
Kiedy słowo kluczowe new tworzy obiekt klasy Osoba, jest on przechowywany w obszarze pamięci zwanym stertą. Referencja znajomy odwołuje się do nowo utworzonego obiektu. Należy również podkreślić, że zmienna znajomy tak naprawdę nie jest obiektem. Przechowuje jedynie informację, gdzie obiekt znajduje się w pamięci.
Możemy przypisywać referencje wielu zmiennym, które jeszcze nie odwołują się do żadnego obiektu. Technika ta jest szczególnie ważna przy implementacji struktur, takich jak drzewa binarne, listy, czy dowolne struktury z dowiązaniami.
Zaprezentujemy kod, który przedstawia klasę o nazwie Osoba, która zawiera pole imie typu String służące do przechowywania imienia osoby. Następnie w głównej metodzie programu utworzymy obiekt klasy Osoba o nazwie znajomy, a do jego pola imie przypiszemy imię „Jan”. W kodzie wykorzystamy również mechanizm referencji poprzez deklarację zmiennej brat typu Osoba, która początkowo jest inicjalizowana jako null, a następnie przypisywana jest do niej referencja do obiektu znajomy.
Kiedy zmienne brat i znajomy wskazują na ten sam obiekt, zmiany dokonane na jednej zmiennej (np. zmiana imienia za pomocą brat.imie = "Artur") będą miały wpływ na obie zmienne, ponieważ obie wskazują na ten sam obiekt. Oznacza to, że zarówno znajomy.imie jak i brat.imie będą teraz równoważne z „Artur”, ponieważ zmieniliśmy imię na obiekcie wskazywanym przez obie zmienne.
Wynik działania programu:
Język Java zawsze przekazuje parametry przez wartość. Choć dla typów prymitywnych jest to dość oczywiste, to jednak dla obiektów charakterystyka ta może budzić wątpliwości. Przeanalizujmy następujący przykład, w którym za pomocą metody zmieniamy stan obiektu.
Wynik działania programu:
Po wywołaniu funkcji zmienImie() to nie wartość obiektu, lecz referencja znajoma jest kopiowana. Błędne jest twierdzenie, że obiekty w języku Java przekazywane są przez referencje. Język Java przekazuje każdy parametr przez wartość niezależnie od jego typu.
Słownik
mechanizm zarządzania pamięcią, który automatycznie identyfikuje i zwalnia pamięć, która nie jest już używana przez program
ogólna zasada przetwarzania zasobów (cyfrowych lub fizycznych), zakładająca obsługiwanie w pierwszej kolejności tych elementów (a zarazem przekazanie ich na wyjście systemu), które jako ostatnie znalazły się na wejściu rozpatrywanego systemu
struktura danych, w której informacje są ulokowane w sposób hierarchiczny
struktura danych, w której informacje są pobierane ze szczytu i na niego odkładane; struktura typu LIFO (Last In, First Out – ostatni na wejściu, pierwszy na wyjściu)
klasa lub interfejs, który jest sparametryzowany względem typów podanych przy deklaracji; aby określić parametr typu, używamy nawiasów ostrych <>; typy generyczne umożliwiają napisanie ogólnej definicji, która działa z różnymi typami, umożliwiając tym samym ponowne użycie kodu, bez konieczności definiowania nowych definicji klas lub interfejsu działających na innym typie zmiennych
zmienne typu prymitywnego przechowują w pamięci konkretne wartości; przykład:
wartości te nie są obiektami