2_referencje

Transkrypt

2_referencje
Uproszczenie : Obiekty są „przekazywane” przez referencję, prymitywy są przekazywane przez wartość
Pełna prawda : Dane i referencje w Javie są przekazywane przez wartość.
Obiekty w ogóle nigdy nie są przekazywane. Przekazywane są tylko referencje do nich.
Wartości:
• zmiennych prostych - są zawsze prymitywami: int, double, char, boolean
• zmiennych obiektowych - są referencjami, nigdy nie są tożsame z obiektami w pamięci,
do których się odnoszą.
Referencja - to informacja o położeniu wartości danej w pamięci. W odróżnieniu od wskaźników,
zarządzanie referencjami realizowane jest wyłącznie przez kompilator lub interpreter, programista nie
ma do tego dostępu. Referencje uniemożliwiają wykonywanie operacji potencjalnie niebezpiecznych,
które w wypadku błędu programisty mogłyby doprowadzić do awarii.
Zmienne obiektowe nie przechowują wartości danych, a jedynie referencje do danych, umieszczonych
na stercie pamięci.
Gdy deklarujesz zmienną prostą, automatycznie przydzielana jest do niej pamięć i możesz od razu
przypisać jej wartość
int n = 10;
Sama deklaracja zmiennej obiektowej nie przydziela pamięci dla obiektu, zadeklarowana zmienna jest na
razie nieokreślona. Trzeba dopiero utworzyć dla niej obiekt wybranej klasy, przy pomocy operatora new
• Operator new wymaga argumentu: konstruktora klasy.
• Operator new zwraca referencję, inaczej: odniesienie do tego obiektu który utworzył.
Możesz przypisać tę referencję do swojej zmiennej obiektowej. Wówczas będzie ona odnosić
się do tego obiektu.
Osoba x = new Osoba();
Tablica – nawet jeśli zawiera tylko elementy o typie prostym, jest obiektem, a obiekt tworzysz
operatorem new.
Rozmiar tablicy może być zmienną ( w C++ to było niedozwolone).
Tablica zawierająca zmienne proste:
int n = 10;
int [] A = new int[n];
// rozmiar tablicy może być zmienną
Random r = new Random();
for (int i = 0; i<n; i++) A[i] = r.nextInt(100);
// wyświetl wszystkie elementy tablicy A
for (int i=0; i<n; i++) System.out.print(A[i]+" ");
// to samo: też wyświetl wszystkie elementy tablicy A, ale za pomocą iteratora
for (int a : A) System.out.print(a+" ");
// a jest tzw. iteratorem
// iterator – jest to obiekt który przyjmuje po kolei wartości wszystkich elementów kontenera (tu:
tablicy)
Tablica zawierająca obiekty wymaga:
• utworzenia obiektu tablicowego i przypisania referencji doń do nazwy tablicy, tak jak
powyżej, a dodatkowo:
• utworzenia obiektu dla każdego elementu i przypisania referencji doń do elementu tablicy,
który także jest zmienną obiektową
Osoba [] X = new Osoba[n];
for (int i = 0; i<n; i++)
X[i] = new Osoba();
System.out.println("\n\nTablica punktów");
Point [] P = new Point[10];
// Point p = new Point(); // tu nie wystarczy jeden raz utworzyć nowy obiekt p
Point p;
// bo kolejnym elementom tablicy P będziesz przypisywać referencję do p
// i wszystkie P[i] odnosiłyby się do tego samego p
for (int i=0; i<10; i++) // jeśli zmienisz wartości p, tak samo zmienią się wszystkie P[i]
{
p = new Point(); // tu trzeba utworzyć nowy obiekt p dla każdego elementu tablicy
p.x = r.nextInt(100);
p.y = r.nextInt(100);
System.out.println(i+" x="+p.x+" y="+p.y);
P[i]=p;
// wówczas elementy P[i] będą mieć różne wartości
}
System.out.println("\nJeszcze raz cała tablica");
for (Point q : P) System.out.println(" x="+q.x+"
y="+q.y);
Można też tak, w ogóle bez zmiennej p, umieszczając losowe wartości wprost w tablicy, ale trzeba każdy obiekt,
odnoszący się do elementu tablicy, utworzyć operatowem new :
Point [] P = new Point[n];
for (int i=0; i<n; i++) {
P[i] = new Point();
P[i].x = r.nextInt(100);
P[i].y = r.nextInt(100);
System.out.println("x="+P[i].x+"
}
y="+P[i].y);
System.out.println("\nJeszcze raz cała tablica");
for (Point q : P) System.out.println(" x="+q.x+"
y="+q.y);