JavaRush /Blog Java /Random-PL /10 uwag na temat modyfikatora statycznego w Javie

10 uwag na temat modyfikatora statycznego w Javie

Opublikowano w grupie Random-PL
Modyfikator statyczny w Javie jest bezpośrednio powiązany z klasą. Jeśli pole jest statyczne, to należy do klasy, jeśli metoda jest statyczna, jest tak samo: należy do klasy. Na tej podstawie można uzyskać dostęp do statycznej metody lub pola przy użyciu nazwy klasy. Na przykład, jeśli pole licznika w klasie Counter jest statyczne, dostęp do zmiennej można uzyskać za pomocą zapytania typu: Counter.count. 10 uwag na temat modyfikatora statycznego w Javie — 1Zanim zaczniemy od notatek, przypomnijmy sobie (i może dowiedzmy się), czym jest statyka i co może być statyczna w Javie. Statyczny to modyfikator stosowany do pola, bloku, metody lub klasy wewnętrznej. Ten modyfikator wskazuje, że podmiot jest powiązany z bieżącą klasą.

Pola statyczne

Kiedy oznaczamy zmienną na poziomie klasy, wskazujemy, że wartość należy do klasy. Jeśli tego nie zrobisz, wartość zmiennej zostanie powiązana z obiektem utworzonym przy użyciu tej klasy. Co to znaczy? 10 uwag na temat modyfikatora statycznego w Javie – 2A faktem jest, że jeśli zmienna nie jest statyczna, to każdy nowy obiekt tej klasy będzie miał swoją wartość tej zmiennej, zmieniając ją zmieniamy ją wyłącznie w jednym obiekcie: Przykładowo mamy klasę Car z nie -zmienna statyczna:
public class Car {
  int km;
}
Następnie w głównym:
Car orangeCar = new Car();
orangeCar.km = 100;

Car blueCar = new Car();
blueCar.km = 85;

System.out.println("Orange car - " + orangeCar.km);
System.out.println("Blue car - " + blueCar.km);
Dane wyjściowe, które otrzymujemy, to:

Orange car - 100
Blue car - 85
Jak widać każdy obiekt ma swoją zmienną, której zmiana następuje tylko dla tego obiektu. Cóż, jeśli mamy zmienną statyczną, to ta wartość globalna jest taka sama dla wszystkich: Teraz mamy samochód ze zmienną statyczną:
public class Car {
  static int km;
}
Następnie ten sam kod w main zostanie wyświetlony na konsoli:

Orange car - 85
Blue car - 85
Przecież dla każdego z nas mamy jedną zmienną i za każdym razem ją zmieniamy. Dostęp do zmiennych statycznych zwykle nie jest możliwy poprzez odwołanie do obiektu - orangeCar.km, ale przez nazwę klasy - Car.km

Blok statyczny

Istnieją dwa bloki inicjujące - zwykły i statyczny. Blok przeznaczony jest do inicjalizacji zmiennych wewnętrznych. Jeśli blok jest normalny, to inicjalizowane są nim zmienne wewnętrzne obiektu, natomiast jeśli jest statyczny, to przypisywane są do nich zmienne statyczne (czyli zmienne klasowe). Przykład klasy ze statycznym blokiem inicjującym:
public class Car {
  static int km;

  static {
     km = 150;
  }
}

Metoda statyczna

Metody statyczne różnią się od zwykłych metod tym, że są również powiązane z klasą, a nie z obiektem. Ważną właściwością metody statycznej jest to, że może ona uzyskać dostęp tylko do zmiennych/metod statycznych. Jako przykład spójrzmy na klasę, która będzie rodzajem licznika śledzącego wywołania metod:
public class Counter {
  static int count;

  public static void invokeCounter() {
     count++;
     System.out.println("Bieżąca wartość licznika - " + count);
  }
}
Nazwijmy to w sposób główny:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
I otrzymujemy dane wyjściowe na konsolę:

Текущее oznaczający счётчика - 1
Текущее oznaczający счётчика - 2
Текущее oznaczający счётчика - 3

Klasa statyczna w Javie

Tylko klasa wewnętrzna może być klasą statyczną. Ponownie, ta klasa jest powiązana z klasą zewnętrzną i jeśli klasa zewnętrzna zostanie odziedziczona przez inną klasę, to ta nie będzie dziedziczona. Co więcej, klasę tę można dziedziczyć, tak samo jak można ją odziedziczyć z dowolnej innej klasy i zaimplementować interfejs. Zasadniczo statyczna klasa zagnieżdżona nie różni się od innych klas wewnętrznych, z tym wyjątkiem, że jej obiekt nie zawiera odniesienia do obiektu klasy zewnętrznej, który ją utworzył. Jednak to sprawia, że ​​klasa statyczna jest najbardziej podobna do zwykłej klasy niezagnieżdżonej, ponieważ jedyną różnicą jest to, że jest ona opakowana w inną klasę. W niektórych przypadkach jest to dla nas zaleta, ponieważ dzięki niemu mamy dostęp do prywatnych zmiennych statycznych klasy zewnętrznej. Przykład zagnieżdżonej klasy statycznej:
public class Vehicle {

  public static class Car {
     public int km;
  }
}
Tworzenie instancji tej klasy i ustawienie wartości zmiennej wewnętrznej:
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
Aby używać statycznych metod/zmiennych/klasy, nie musimy tworzyć obiektu tej klasy. Oczywiście należy wziąć pod uwagę modyfikatory dostępu. Na przykład pola privatesą dostępne tylko w obrębie klasy, w której są zadeklarowane. Pola protectedsą dostępne dla wszystkich klas wewnątrz pakietu ( package ), jak również dla wszystkich klas potomnych poza pakietem. Aby uzyskać więcej informacji, zapoznaj się z artykułem „ prywatny a chroniony vs publiczny ”. increment()Załóżmy, że w klasie istnieje metoda statyczna Counter, której zadaniem jest zwiększanie licznika count. Aby wywołać tę metodę, można skorzystać z wywołania formularza Counter.increment(). Nie ma potrzeby tworzenia instancji klasy, Counteraby uzyskać dostęp do statycznego pola lub metody. Jest to podstawowa różnica pomiędzy obiektami statycznymi i niestatycznymi (elementami klasy). Przypomnę jeszcze raz, że elementy klasy statycznej należą bezpośrednio do klasy, a nie do jej instancji. Oznacza to, że wartość zmiennej statycznej countbędzie taka sama dla wszystkich obiektów typu Counter. W dalszej części tego artykułu przyjrzymy się podstawowym aspektom używania modyfikatora statycznego w Javie, a także niektórym funkcjom, które pomogą Ci zrozumieć kluczowe koncepcje programistyczne.

Co każdy programista powinien wiedzieć o modyfikatorze Static w Javie

W tej sekcji przyjrzymy się podstawom używania statycznych metod, pól i klas. Zacznijmy od zmiennych.
  1. NIE można uzyskać dostępu do niestatycznych elementów klasy w kontekście statycznym, takim jak metoda lub blok. 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
    }}

    Jest to jeden z najczęstszych błędów popełnianych przez programistów Java, szczególnie początkujących. Ponieważ metoda mainjest statyczna, ale zmienna countnie, w tym przypadku metoda printlnwewnątrz metody mainzgłosi „Błąd czasu kompilacji”.

  2. В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких Jak «состояние гонки» (race condition).

  3. Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый obiekt для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы Jak нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утLubт (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утLubты в Java финализированы (final).

  4. Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) zamiast переопределения. Это явление известно Jak сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен Jak в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

    class Vehicle{
         public static void  kmToMiles(int km){
              System.out.println(„Wewnątrz klasy nadrzędnej/metody statycznej”);
         } }
    
    class Car extends Vehicle{
         public static void  kmToMiles(int km){
              System.out.println(„Wewnątrz klasy potomnej/metody statycznej”);
         } }
    
    public class Demo{
       public static void main(String args[]){
          Vehicle v = new Car();
           v.kmToMiles(10);
      }}

    Вывод в консоль:

    Внутри родительского класса/статического метода

    Код наглядно демонстрирует: несмотря на то, что obiekt имеет тип Car, вызван статический метод из класса Vehicle, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло!

  5. Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны Jak «вложенные статические классы» (nested static class). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса — HashMap.Entry, который предоставляет структуру данных внутри HashMap. Стоит заметить, также Jak и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявLub пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator), например компаратор по возрасту (AgeComparator) в классе сотрудники (Employee).

  6. Модификатор static также может быть объявлен в статичном блоке, более известным Jak «Статический блок инициализации» (Static initializer block), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

  7. Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных Lub не статических методов, которые связываются во время исполнения на реальном obiektе. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности Lub необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утLubты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка.

  8. Важным свойством статического блока является инициализация. Статические поля Lub переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз, в том же порядке, в Jakом они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна Singleton. Если вы не используется список Enum Jak Singleton, по тем Lub иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё ДО того Jak кто-нибудь об этом «попросит». Если obiekt ресурсоёмкий Lub редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу.

  9. Podczas serializacji, podobnie jak transientzmienne, pola statyczne nie są serializowane. Rzeczywiście, jeśli zapiszesz jakiekolwiek dane w polu statycznym, to po deserializacji nowy obiekt będzie zawierał swoją pierwotną (domyślną) wartość, przykładowo jeśli pole statyczne było zmienną typu int, to jego wartość po deserializacji będzie wynosić zero, jeśli typ floatto 0.0, jeśli typ Objectnull. Szczerze mówiąc, jest to jedno z najczęściej zadawanych pytań dotyczących serializacji w wywiadach w języku Java. Nie przechowuj najważniejszych danych o obiekcie w polu statycznym!

  10. I na koniec porozmawiajmy o static import. Modyfikator ten ma wiele wspólnego ze standardowym operatorem import, ale w przeciwieństwie do niego pozwala na import jednego lub wszystkich statycznych elementów klasy. Importując metody statyczne, można uzyskać do nich dostęp tak, jakby były zdefiniowane w tej samej klasie, podobnie importując pola, możemy uzyskać do nich dostęp bez podawania nazwy klasy. Ta funkcja została wprowadzona w Javie w wersji 1.5 i właściwie wykorzystana poprawia czytelność kodu. Konstrukcję tę najczęściej spotyka się w testach JUnit , ponieważ Prawie wszyscy twórcy testów używają static importna przykład metod asercji assertEquals()i ich przeciążonych duplikatów. Jeśli nic nie jest jasne, zapraszamy po dodatkowe informacje .

To wszystko. Każdy programista musi znać wszystkie powyższe punkty dotyczące modyfikatora statycznego w Javie . W tym artykule omówiono podstawowe informacje o zmiennych statycznych, polach, metodach, blokach inicjujących i importach. Zawiera kilka ważnych właściwości, których znajomość jest kluczowa przy pisaniu i rozumieniu programów w Javie. Mam nadzieję, że każdy programista będzie doskonalił swoje umiejętności w posługiwaniu się koncepcjami statycznymi, ponieważ... Jest to bardzo ważne w przypadku poważnego programowania.”
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION