CodeGym /Blog Java /Poland /Metody statyczne w Javie
Autor
Pavlo Plynko
Java Developer at CodeGym

Metody statyczne w Javie

Opublikowano w grupie Poland
Modyfikator statyczny w Javie oznacza, że coś jest bezpośrednio związane z klasą: jeśli pole jest statyczne, to należy do klasy; jeśli metoda jest statyczna, to należy do klasy. W rezultacie, możesz użyć nazwy klasy, aby wywołać metodę statyczną lub odnieść się do pola statycznego. Na przykład, jeśli pole count jest statyczne w klasie Counter, możesz odnieść się do zmiennej przy pomocy poniższego wyrażenia: Counter.count. Oczywiście, trzeba także wziąć pod uwagę modyfikatory dostępu. Przykładowo, pola private dostępne są tylko od wewnątrz klasy, w której są zadeklarowane, podczas gdy pola protected dostępne są dla wszystkich klas w pakiecie, a także dla ich wszystkich podklas poza pakietem. Załóżmy, że w klasie Counter znajduje się statyczna metoda increment(), której zadaniem jest inkrementacja pola count. Aby wywołać tę metodę, możesz użyć Counter.increment(). Nie ma potrzeby tworzyć instancji klasy Counter, aby mieć dostęp do pola lub metody statycznej. Taka jest głównie różnica pomiędzy zmiennymi i metodami statycznymi (klasy) oraz NIE-statycznymi (instancji) zmiennymi i metodami Musisz jednak pamiętać o pewnej rzeczy. Statyczne części klasy należą bezpośrednio do klasy, a nie do instancji klasy. To znaczy, że zmienna statyczna count ma taką samą wartość dla wszystkich obiektów Counter. W tym artykule przyjrzymy się głównym aspektom używania modyfikatora statycznego w Javie, a także pewnym funkcjom, które pomogą Ci zrozumieć kluczowe koncepcje programowania.Metody statyczne w Javie - 1

Metoda statyczna w Javie - co każdy programista powinien o niej wiedzieć?

W tej sekcji przeanalizujemy główne aspekty korzystania ze statycznych metod, pól i klas. Zacznijmy od zmiennych.
  1. NIE MOŻESZ uzyskać dostępu do niestatycznych elementów składowych klasy wewnątrz kontekstu statycznego, np. statycznej metody czy bloku. Kompilacja poniższego kodu zakończy się błędem:

    
    public class Counter {
    private int count;
    public static void main(String args []) {
       System.out.println(count); //  Compile time error
    }
    }
    

    To jeden z najpowszechniejszych błędów popełnianych przez programistów Java, zwłaszcza tych początkujących. Jeśli metoda main jest statyczna, a zmienna count nie, użycie metody println wewnątrz metody main spowoduje wystąpienie „błędu kompilacji”.

  2. W przeciwieństwie do zmiennych lokalnych, pola i metody statyczne NIE są w Javie thread safe. W praktyce jest to jedna z najczęstszych przyczyn problemów z bezpieczeństwem w programowaniu wielowątkowym. Ponieważ każda instancja klasy odnosi się do tej samej kopii zmiennej statycznej, zmienna ta powinna być chroniona lub „zablokowana” przez klasę. A zatem, musisz się upewnić, że zmienne statyczne, których masz używać, są prawidłowo synchronized. Dzięki temu unikniesz takich problemów jak race conditions.

  3. Metody statyczne mają w praktyce tę przewagę, że nie ma potrzeby tworzenia nowego obiektu za każdym razem, gdy chcesz je wywołać. Metoda statyczna w Javie może zostać wywołana przy użyciu nazwy klasy, która ją deklaruje. To dlatego metody te są idealne dla metod factory i metod utility. Znakomitym przykładem jest klasa java.lang.Math: prawie wszystkie jej metody są statyczne. Klasy utility w Javie oznaczone są jako final nie bez powodu.

  4. Kolejną ważną kwestią jest to, że nie możesz nadpisywać (@Override) metod statycznych. Jeśli zadeklarujesz identyczną metodę w subclass, czyli metodę o takiej samej nazwie i sygnaturze, jedynie „ukrywasz” metodę superclass zamiast ją nadpisać. Ten fenomen znany jest jako method hiding. Oznacza to, że jeśli metoda statyczna zadeklarowana jest zarówno w klasie macierzystej, jak i podrzędnej, wywoływana metoda zawsze będzie opierać się na typie zmiennej podczas kompilacji. Inaczej dzieje się podczas nadpisywania metod - metody te nie zostaną wykonane, kiedy program ruszy. Rozważmy taki przykład:

    
    class Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the parent class / static method");
         } 
    }
    
    class Car extends Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the child class / static method");
         } 
    }
    
    public class Demo {   
       public static void main(String args []) {
          Vehicle v = new Car();
           v.kmToMiles(10);
      }
    }
    

    Wyjście konsoli:

    Inside the parent class / static method

    W kodzie widać wyraźnie, że mimo faktu, iż obiekt to Car, wywoływana jest metoda statyczna w klasie Vehicle, jako że metoda ta została wywołana podczas kompilacji. Zauważ, że nie wystąpiły żadne błędy kompilacji!

  5. Co więcej, w przeciwieństwie do tych zwykłych klas, możesz zadeklarować klasy statyczne wewnątrz innych klas. Takie klasy statyczne w Javie znane są jako nested static classes. Są one bardzo przydatne i zapewniają lepszą spójność. Uderzającym przykładem statycznej klasy wewnętrznej jest HashMap.Entry, która jest strukturą danych wewnątrz HashMap. Warto zauważyć, że - tak jak klasy inner - statyczne klasy wewnętrzne zadeklarowane są w oddzielnym pliku .class. To oznacza, że jeśli zadeklarujesz pięć wewnętrznych klas w Twojej klasie głównej, otrzymasz 6 plików z rozszerzeniem .class. Kolejnym przykładem jest zadeklarowanie własnego Comparator, na przykład komparatora wieku (AgeComparator) w klasie Employee.

  6. Modyfikator statyczny może także być używany w statycznym bloku inicjalizacyjnym, zwanym zazwyczaj po prostu „blokiem statycznym”, który wykonywany jest, gdy klasa zostanie załadowana. Jeśli nie zadeklarujesz takiego bloku, Java zbiera wszystkie pola statyczne w jedną listę i inicjalizuje je, gdy klasa zostanie załadowana. Blok statyczny NIE MOŻE wyrzucać wyjątków checked, może jednak wyrzucać unchecked. W tym przypadku pojawi się ExceptionInInitializerError. W praktyce, każdy dowolny wyjątek, który się pojawi podczas inicjalizacji pól statycznych, zostanie włączony w ten błąd przez Javę. Jest to także najpowszechniejsza przyczyna NoClassDefFoundError, ponieważ klasa ta nie zostanie odnaleziona w pamięci, kiedy nastąpi do niej odniesienie.

  7. Dobrze jest wiedzieć, że metody statyczne są połączone podczas kompilacji, w przeciwieństwie do łączenia metod wirtualnych lub niestatycznych, które łączą się podczas uruchamiania, kiedy zostają wywołane na konkretnym obiekcie. Odpowiednio, metody statyczne nie mogą być nadpisywane w Javie, ponieważ podczas uruchamiania polimorfizm nie ma w stosunku do nich zastosowania. Ważne, aby uwzględnić to ograniczenie podczas deklarowania metody statycznej. Takie postępowanie ma sens tylko wtedy, kiedy nie ma możliwości lub potrzeby nadpisywania metody w podklasie. Metody wytwórcze i metody utility to dobre przykłady prawidłowego użycia modyfikatora statycznego. Joshua Bloch w swojej książce Java. Efektywne programowanie (swoją drogą, obowiązkowa pozycja dla każdego programisty w Javie) wskazuje na znaczącą przewagę statycznych metod wytwórczych nad konstruktorami.

  8. Inicjalizacja to ważny aspekt bloku statycznego. Pola lub zmienne statyczne są inicjalizowane po tym, jak klasa zostaje załadowana do pamięci. Ich inicjalizacja wykonywana jest od góry do dołu, w takiej samej kolejności, w jakiej są one deklarowane w pliku źródłowym w klasie Java. Ponieważ pola statyczne są inicjalizowane w sposób bezpieczny dla wątku, proces ten jest także używany do implementowania wzoru Singleton. Jeżeli nie używasz z jakiegoś powodu Enum jako swojego Singleton, to masz dobrą alternatywę. Ale w tym przypadku, musisz wziąć pod uwagę, że nie jest to „leniwa” inicjalizacja. To znaczy, że pole statyczne będzie inicjalizowane jeszcze ZANIM ktoś o to „poprosi”. Jeśli obiekt jest rzadko używany lub wymaga dużej ilości zasobów, to inicjalizowanie go w bloku statycznym nie zadziała na Twoją korzyść.

  9. Podczas serializacji pola statyczne, jak zmienne transient, nie są serializowane. Wszelkie dane zapisane w polu statycznym będą po deserializacji zawierać jego początkową (domyślną) wartość. Na przykład, jeśli pole statyczne jest typu int, jego wartość po deserializacji wyniesie zero. Jeśli jego typ to float, wartość będzie równa 0.0. A jeśli będzie ono typu Object, wartość wyniesie null. Szczerze mówiąc, jest to jedno z najpopularniejszych pytań o serializację zadawanych podczas rozmów rekrutacyjnych na stanowiska związane z Javą. Nie przechowuj znaczących danych obiektu w polu statycznym!

  10. Na koniec porozmawiajmy o imporcie statycznym. Tego typu użycie modyfikatora statycznego to zwrot w standardowej instrukcji import. Różni się tym, że pozwala zaimportować jeden bądź wszystkie elementy składowe klasy statycznej. Kiedy metody statyczne zostaną już zaimportowane, można uzyskać do nich dostęp tak, jak gdyby były zadeklarowane w tej samej klasie. W podobny sposób, importując pola statyczne, możemy mieć do nich dostęp bez określania nazwy klasy. Funkcja ta pojawiła się w Javie 1.5 i, o ile używana jest w prawidłowy sposób, poprawia czytelność kodu. Konstrukcję tę można najczęściej znaleźć w testach JUnit, jako że praktycznie wszyscy programiści testów używają importu statycznego dla metod assert, np. assertEquals() i jej przeładowanych wariantów.

  11. To na razie wszystko. Każdy programista Java musi znać wszystkie wymienione wyżej aspekty tematyki modyfikatorów statycznych. W artykule tym przeanalizowaliśmy podstawowe informacje o statycznych: zmiennych, polach, metodach, blokach inicjalizacyjnych oraz importach. Napomknęliśmy także o pewnych ważnych właściwościach, kluczowych dla pisania i rozumienia programów w Javie. Mamy nadzieję, że każdy programista będzie udoskonali swój sposób używania składowych statycznych, co jest niezwykle ważne w prawidłowym programowaniu.”

Ten artykuł przeczytasz także po angielsku.
Read the English version of this article to become an expert on Java’s static keyword. It points out some of the nuances of static Java classes and static methods in Java.
Metody statyczne w Javie - 2
Komentarze (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Michał Poziom 7, Przeworsk, Poland
14 listopada 2022
mam drugi poziom i nic nie rozumiem xd, wrócę tutaj za jakiś czas