Menu

Składowe statyczne w Javie: pola i metody static

Co robi słowo kluczowe static w Javie, jak pola i metody statyczne należą do klasy zamiast do obiektów i kiedy sięgać po bloki statyczne i stałe.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Należy do klasy, a nie do obiektu

Większość pól i metod napisanych do tej pory należy do obiektów: przy każdym new każda instancja dostaje własną kopię pól, a metody działają na stanie tego konkretnego obiektu. Słowo kluczowe static to odwraca. Składowa static należy do samej klasy: jest jedna kopia, współdzielona przez wszystkie instancje, i istnieje niezależnie od tego, czy kiedykolwiek utworzysz obiekt.

To jedno rozróżnienie wyjaśnia pola statyczne, metody statyczne, stałe, a nawet to, dlaczego main zawsze jest static.

Współdzielone pole static

Pole niestatyczne daje każdemu obiektowi własne miejsce. Pole static daje klasie jedno miejsce, które wszyscy współdzielą. Klasyczny przykład to licznik, który śledzi, ile obiektów utworzono:

Zwróć uwagę, że licznik odczytujesz jako User.count, czyli przez nazwę klasy, bo wartość nie należy do żadnego pojedynczego User. Każde name natomiast mieszka we własnym obiekcie. Zmień count przez dowolną instancję, a każda instancja zobaczy nową wartość, bo istnieje tylko jedna.

Metody static

Metoda static też należy do klasy, więc wywołujesz ją na klasie, bez obiektu:

Dokładnie według tego wzorca działa biblioteka standardowa: Math.max, Integer.parseInt, Arrays.sort i List.of są static, bo to zachowania narzędziowe, które nie potrzebują obiektu. Sięgaj po metodę static, gdy praca zależy tylko od argumentów, a nie od stanu konkretnego obiektu.

Wielka pułapka: static nie widzi instancji

Metoda static działa bez żadnego obiektu, więc nie ma this. Oznacza to, że nie może bezpośrednio używać pól instancji ani wywoływać metod instancji, bo nie ma konkretnego obiektu, z którego mogłaby je odczytać. To najczęstszy błąd początkujących związany ze static:

class Account {
    int balance = 100;          // pole instancji

    static int show() {
        return balance;         // BŁĄD KOMPILACJI: do niestatycznego pola 'balance'
    }                           // nie można się odwołać z kontekstu statycznego
}

Rozwiązaniem jest zamiana metody na metodę instancji (usuń static, żeby miała this) albo jawne przekazanie obiektu:

W drugą stronę wszystko działa: metoda instancji może swobodnie czytać pola static i wywoływać metody static, bo współdzielone dane na poziomie klasy zawsze istnieją.

Stałe przez static final

Połącz static z final, a dostaniesz stałą: jedną współdzieloną wartość, której nie da się zmienić. Zgodnie z konwencją nazywa się je w stylu UPPER_SNAKE_CASE:

static final to idiomatyczny sposób na wyrażenie "stałej wartości należącej do typu", jak Integer.MAX_VALUE czy Math.PI w bibliotece standardowej. static sprawia, że nie marnujesz kopii na każdy obiekt; final sprawia, że nikt nie może jej przypisać na nowo.

Statyczne bloki inicjalizacyjne

Proste pole static można zainicjalizować w miejscu deklaracji. Gdy przygotowanie wymaga prawdziwej logiki, np. budowy tabeli wyszukiwania przez HashMap albo odczytu konfiguracji, użyj bloku static. Wykonuje się raz, przy pierwszym załadowaniu klasy, zanim powstanie jakikolwiek obiekt:

Blok uruchamia się jeden raz, niezależnie od tego, ile razy używasz klasy, więc to właściwe miejsce na jednorazową konfigurację dla całej klasy.

Kiedy używać static

Prosta zasada:

  • Używaj pola static tylko dla danych naprawdę współdzielonych przez wszystkie instancje: licznika, cache'u, stałej. Jeśli dwa obiekty mogłyby rozsądnie mieć różne wartości, powinno to być pole instancji.
  • Używaj metody static, gdy wynik zależy tylko od argumentów, a nie od stanu obiektu (czyste funkcje narzędziowe).
  • Domyślnie wybieraj składowe instancji. Nadużywanie static po cichu zamienia program w stertę stanu globalnego, który trudno testować i analizować. static to wyjątek, a nie punkt wyjścia.

Dalej: enumy

Stała static final wystarcza dla jednej ustalonej wartości, ale gdy masz mały, stały zestaw powiązanych wartości, np. kierunki, dni tygodnia czy statusy zamówień, Java ma specjalny typ, który jest bezpieczniejszy i bardziej wyrazisty niż rozrzucone stałe. To enum i o nim jest następna strona.

Najczęściej zadawane pytania

Co oznacza static w Javie?

static oznacza, że pole lub metoda należy do samej klasy, a nie do konkretnego obiektu. Istnieje dokładnie jedna kopia pola static, współdzielona przez wszystkie instancje, a metodę static wywołuje się na klasie (Math.max(...)) bez potrzeby tworzenia obiektu. Składowe niestatyczne (instancyjne) mają natomiast osobną kopię w każdym obiekcie.

Czym różnią się zmienne statyczne od zmiennych instancji w Javie?

Zmienna instancji ma jedną wartość na obiekt: dwa obiekty mogą mieć różne wartości. Zmienna static ma jedną wartość współdzieloną przez wszystkie obiekty klasy, więc jej zmiana przez jeden obiekt (albo przez nazwę klasy) jest widoczna dla wszystkich pozostałych. Używaj pól instancji do stanu każdego obiektu, a pól static do danych naprawdę globalnych dla klasy, np. licznika albo stałej.

Dlaczego metoda main w Javie jest static?

JVM musi wywołać main, zanim powstanie jakikolwiek obiekt twojej klasy. Ponieważ metoda static należy do klasy, a nie do instancji, środowisko uruchomieniowe może wywołać Main.main(args) bezpośrednio, bez wcześniejszego tworzenia obiektu Main. Dlatego sygnatura zawsze brzmi public static void main(String[] args).

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ