– Przejdźmy teraz do innego tematu. Przeanalizujmy zmienne i metody statyczne.

– Basiu, ja już się uczyłem o zmiennych i metodach statycznych. Ale mógłbym poznać więcej szczegółów.

– Kiedy deklarujemy zmienne w klasie, definiujemy, czy mają one zostać utworzone tylko raz, czy też każda instancja (obiekt) klasy będzie miała swoją własną kopię. Domyślnie tworzy się nową kopię zmiennej dla każdego obiektu. Wygląda to tak:

Deklaracja klasy
class Kot                        // Klasa
{
    String imie;                 // Zmienna

    Kot(String imie)             // Konstruktor
    {
        this.imie = imie;        // Inicjalizacja zmiennej
    }
}
Kod w metodzie main:
Kot kot1 = new Kot("Oskar"); // Tworzy jeden obiekt, którego zmienna imie zawiera "Oskar"
Kot kot2 = new Kot("Mania"); // Tworzy jeden obiekt, którego zmienna imie zawiera "Mania"
System.out.println(kot1.imie);
System.out.println(kot2.imie);
Wynik na ekranie
Oskar
Mania

– Pomimo deklaracji ich w tej samej klasie (Kot), zmienne kot1.imie i kot2.imie zawierają różne wartości, ponieważ odnoszą się do różnych obiektów.
– To ma sens.
– Jednak dla każdej instancji klasy istnieje tylko jedna kopia zmiennej statycznej i należy uzyskać do niej dostęp, używając nazwy klasy.

Deklaracja klasy
class Kot                        // Klasa
{
    String imie;            // Zmienna instancji (niestatyczna)
    static int licznikKotow;    // Zmienna statyczna

    Kot(String imie)
    {
        this.imie = imie;
        Kot.licznikKotow++;   // Przyrost zmiennej statycznej o 1
    }
}
Kod w metodzie main:
System.out.println(Kot.licznikKotow);
Kot kot1 = new Kot("Oskar");

System.out.println(Kot.licznikKotow);
Kot kot2 = new Kot("Mania");

System.out.println(kot1.imie);
System.out.println(kot2.imie);
System.out.println(Kot.licznikKotow);
Wynik na ekranie:
0
1
Oskar
Mania
2

– OK, to także ma sens.

– Metody w Javie dzielą się na dwie kategorie. Metody instancji – są wywoływane na obiekcie i mają dostęp do danych tego obiektu. Metody statyczne – nie mają takiego dostępu, ponieważ po prostu nie mają referencji do obiektu. Mogą jednak odnosić się do zmiennych statycznych klasy i innych metod statycznych.

Metody statyczne nie mogą odnosić się do niestatycznych metod lub niestatycznych zmiennych!

– Dlaczego tak jest, Basiu?

– Każda zmienna instancji jest zawarta w obiekcie. Uzyskuje się do niej dostęp pod warunkiem, że ma się referencję do tego obiektu. Taka referencja nie jest dostępna dla metody statycznej.

– Czy metody instancji mają taką referencję?

– Tak, jest ona pośrednio przekazywana do metod instancji. Referencja do obiektu, na którym metoda instancji jest wywoływana, zostaje pośrednio przekazana metodzie instancji. Zmienna, która przechowuje tę referencję, jest nazywana this. To pozwala metodzie zawsze mieć dostęp do danych obiektu lub wywołać inną, niestatyczną metodę na tym samym obiekcie.

Zamiast referencji do obiektu, do metody statycznej przekazywana jest wartość null. To dlatego nie mogą one być przypisane do niestatycznych zmiennych i metod. One po prostu nie mają referencji do obiektu związanego z tymi zmiennymi i metodami.

– OK, Basiu, rozumiem.

– Oto, jak działają metody niestatyczne:

Jak wygląda kod
Kot kot = new Kot();
String imie = kot.getImie();
kot.setWiek(17);
kot.setDzieci(kot1, kot2, kot3);
I co się naprawdę wtedy dzieje
Kot kot = new Kot();
String imie = Kot.getImie(kot);
Kot.setWiek(kot, 17);
Kot.setDzieci(kot, kot1, kot2, kot3);
Kiedy wywołujesz metodę, używając zapisu <obiekt> kropka <nazwa metody>, tak naprawdę wywołujesz metodę klasy i przekazujesz ten obiekt jako pierwszy argument. Wewnątrz metody ten obiekt jest nazywany 'this'. Wszystkie operacje w metodzie są przeprowadzane na tym obiekcie i jego danych.

– Oto, jak działają metody statyczne:

Jak wygląda kod
Kot kot1 = new Kot();
Kot kot2 = new Kot();
int licznikKotow = Kot.getLicznikWszystkichKotow();
I co się naprawdę wtedy dzieje
Kot kot1 = new Kot();
Kot kot2 = new Kot();
int licznikKotow = Kot.getLicznikWszystkichKotow(null);
Kiedy wywołujesz metodę statyczną, nie jest do niej przekazany żaden obiekt. Innymi słowy 'this' jest równe null. To dlatego metoda statyczna nie może mieć dostępu do niestatycznych zmiennych i metod (ponieważ nie ma niczego do domyślnego przekazania metodom niestatycznym).

– Zmienna lub metoda jest statyczna, jeśli jest poprzedzona słowem static w kodzie.

– Po co nam te metody, skoro są one tak bardzo ograniczone?

– Cóż, mają swoje zalety.

– Po pierwsze, nie musimy przekazywać referencji do obiektu, aby użyć statycznych metod i zmiennych.

– Po drugie, czasem jest niezbędne, by mieć jedną i tylko jedną kopię zmiennej. Na przykład System.out (statyczna zmienna wyjściowa klasy System).

– Po trzecie, czasem musisz wywołać metodę, zanim będziesz w stanie utworzyć obiekty.

– Basiu, może podasz mi jakiś przykład?

– Dlaczego uważasz, że metoda main() jest statyczna? Jest statyczna, ponieważ programista może wywołać ją od razu po załadowaniu klasy do pamięci, jeszcze zanim jakikolwiek obiekt zostanie utworzony.