Nauka programowania Java #5: Metody statyczne

Na pewno spotkałeś/aś się z określeniem, że w Javie wszystko jest klasą. W rzeczywistości faktem jest, że każdy napisany przez nas kod MUSI zawierać sie w jakiejś klasie. To wymuszenie sprawia, że Java faktycznie jest językiem w pełni obiektowym.
Przypomnij sobie proszę metodę main, dzięki której odpalić można program w Javie. Sygnatura takiej metody zawsze wygląda tak:

public static void main(String [] args)

W każdej metodzie main należy zawrzeć słowo kluczowe static. Umożliwia ono używanie metody bez tworzenia obiektu. Tak, nie przesłyszałeś/aś się, w Javie można używać metod w klasach bez uprzedniego stworzenia jej obiektu. Takie podejście nazywamy programowaniem strukturalnym a nie obiektowym. Popatrz na przykład poniżej.

public class StructuralProgramming {
  static void showMessage(String message) {
    System.out.println(message);
  }
  
  static int add(int valueOne, int valueTwo) {
    return valueOne + valueTwo;
  }
}
public class MainClass {
  static void main(String[] args) {
    int sum = StructuralProgramming.add(10, 20);
    System.out.println(sum);
    StructuralProgramming.showMessage("test message");
  }
}

 

Na konsoli wyświetli się:
30
test message

Statyczne metody możesz używać zawsze, gdy pozwoli Ci na to modyfikator dostępu (w przypadku, gdy jest to dostęp pakietowy, co oznacza, że każda klasa w pakiecie może jej używać). Aby wywołać metodę statyczną, nie tworzysz jej obiektu, wystarczy odwołać się do nazwy klasy i po kropce wybrać odpowiednią metodę. Jest to bardzo wygodne rozwiązanie, ale niestety, jak wszystko w życiu, ma swoją cenę. Wyobraź sobie, że masz system, który zawiera miliony klas. Pracują nad nimi dziesiątki deweloperów rozsianych po całym świecie. Nagle każdy zaczyna używać sobie twojej metody statycznej bez deklaracji obiektu. Po paru dniach system przestał działać i nikt nie jest wstanie stwierdzić dlaczego, ponieważ metoda była używana globalnie, bez względu na to, czy tworzone po drodze obiekty faktycznie pozwalały na jej użycie. Sprawdzenie teraz kilkuset klas, gdzie użyto statycznej metody, zajęło programistom tygodnie, a firma w tym czasie zbankrutowała. Dostrzegasz teraz niebezpieczeństwo używania takich metod? Są jednak sytuacje, kiedy warto używać statycznych (czyli klasowych) metod. Na przykład, gdy tworzysz bezstanową metodę pomocniczą, która liczy średnią ważoną. Metoda bezstanowa, to taka, która nie modyfikuje żadnych zmiennych referencyjnych (obiektów, tablic, itp.). Taką metodę możemy użyć zawsze w systemie bez obawy, że coś komuś przypadkiem nadpiszemy (na przykład poprzez podmienienie referencji, itp).

Abyś lepiej pojął różnice między programowaniem obiektowym i strukturalnym, spójrz proszę na ten przykład:

public class Car {
  String model;
  
  void showMeCar() {
    System.out.println("Car model is: " + model);
  }
}

public class StructuralProgramming {
  static void showMessage(String message) {
    Car car = new Car(null, 0);
    car.showMeCar();
    System.out.println(message);
  }
  
  static int add(int valueOne, int valueTwo) {
    return valueOne + valueTwo;
  }
}

Jak widzisz bez problemu można zagnieżdżać w metodach statycznych obiekty. Nie ma też żadnych problemów, aby statyczne metody wywoływać w metodach niestatycznych w obiektach. Problem zaczyna się, gdy zaczynasz mieszać metody statyczne i niestatyczne w jednej klasie.

public class StructuralProgramming {
  String name;
  
  static void showMessage(String message) {
    add(1,2); // Error: Cannot make a static reference to the non-static method
    System.out.println(message + " " + name); // Error: Cannot make a static reference to the non-static field name
  }
  
  int add(int valueOne, int valueTwo) {
    return valueOne + valueTwo;
  }
}

Tak napisany kod się nieskompiluje. Dzieje się tak dlatego, że nie można używać zmiennych/metod niestatycznych (instancyjnych) w metodach statycznych. Przypominam raz jeszcze, że metody statyczne to metody klasowe i działają niezależnie od tworzonych obiektów tej klasy przez cały czas działania programu. Poniżej przedstawiam jak powinien wyglądać powyższy kod prawidłowo:

public class StructuralProgramming {
  static String name;
  
  static void showMessage(String message) {
    add(1,2);
    System.out.println(message + " " + name);
  }
  
  static int add(int valueOne, int valueTwo) {
    return valueOne + valueTwo;
  }
}

Jedna myśl na temat “Nauka programowania Java #5: Metody statyczne

  1. bardzo dziękuję za ten wpis – poukładał mi co nieco w głowie. Jedynie uważam, że przykład jest niepełny. Przydałoby się podsumowanie kodu – wraz ze wskazaniem – dlaczego ta zmienna (w tym przypadku name) powoduje konflikt. Dlaczego nie mogę podać stałych jako parametry metody w innej metodzie.
    Z tematem gryzłem się już jakiś czas i po przeczytaniu artykułu wszystko się ułożyło w logiczną całość, o tyle dla osób dopiero zabierających się za temat artykuł może być niewystarczający.

    Niemniej bardzo dziękuję za pomoc!

Dodaj komentarz