JavaRush/Java Blog/Random EN/10 Notes on the Static Modifier in Java

10 Notes on the Static Modifier in Java

Published in the Random EN group
members
The static modifier in Java is directly associated with the class. If the field is static, then it belongs to the class, if the method is static, it’s the same: it belongs to the class. Based on this, you can access a static method or field using the class name. For example, if the count field is static in the Counter class, then you can access the variable with a query like: Counter.count. 10 Notes on the Static Modifier in Java - 1Before we start with the notes, let's remember (and maybe find out) what static is and what can be static in Java. Static is a modifier applied to a field, block, method, or inner class. This modifier indicates that the subject is bound to the current class.

Static fields

When we denote a class-level variable, we indicate that the value belongs to a class. If you do not do this, then the value of the variable will be bound to an object created using this class. What does it mean? 10 Notes on the Static Modifier in Java - 2And the fact is that if the variable is not static, then each new object of this class will have its own value of this variable, by changing which we change it exclusively in one object: For example, we have a Car class with a non-static variable:
public class Car {
  int km;
}
Then in main:
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);
The output we get is:

Orange car - 100
Blue car - 85
As you can see, each object has its own variable, the change of which occurs only for this object. Well, if we have a static variable, then this global value is the same for everyone: Now we have a Car with a static variable:
public class Car {
  static int km;
}
Then the same code in main will output to the console:

Orange car - 85
Blue car - 85
After all, we have one variable for all of us, and every time we change it. Static variables are usually accessed not by an object reference - orangeCar.km, but by the class name - Car.km

Static block

There are two initialization blocks - regular and static. The block is intended to initialize internal variables. If the block is normal, then the internal variables of the object are initialized with it, but if it is static, then static variables (that is, class variables) are assigned to them. Example of a class with a static initialization block:
public class Car {
  static int km;

  static {
     km = 150;
  }
}

Static method

Static methods differ from regular methods in that they are also bound to a class rather than an object. An important property of a static method is that it can only access static variables/methods. As an example, let's look at a class that will be a kind of counter that keeps track of method calls:
public class Counter {
  static int count;

  public static void invokeCounter() {
     count++;
     System.out.println("Current counter value - " + count);
  }
}
Let's call it in main:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
And we get the output to the console:

Текущее meaning счётчика - 1
Текущее meaning счётчика - 2
Текущее meaning счётчика - 3

Static class in Java

Only an inner class can be a static class. Again, this class is tied to the outer class, and if the outer one is inherited by another class, then this one will not be inherited. Moreover, this class can be inherited, just as it can be inherited from any other class and implement an interface. Essentially, a static nested class is no different from any other inner class, except that its object does not contain a reference to the outer class object that created it. However, this makes a static class most similar to a regular non-nested one, because the only difference is that it is wrapped in another class. In some cases, this is an advantage for us, since from it we have access to the private static variables of the outer class. Example of a nested static class:
public class Vehicle {

  public static class Car {
     public int km;
  }
}
Creating an instance of this class and setting the value of the internal variable:
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
To use static methods/variables/class, we do not need to create an object of that class. Of course, access modifiers should be taken into account. For example, fields privateare only accessible within the class in which they are declared. Fields protectedare available to all classes inside a package ( package ), as well as to all descendant classes outside the package. For more details, check out the article “ private vs protected vs public ”. Suppose there is a static method increment()in the class Counterwhose task is to increment the counter count. To call this method, you can use an invocation of the form Counter.increment(). There is no need to instantiate a class Counterto access a static field or method. This is the fundamental difference between static and NON-static objects (class members). Let me remind you once again that static class members directly belong to the class, not to its instance. That is, the value of a static variable countwill be the same for all objects of type Counter. Later in this article, we'll look at the fundamental aspects of using the static modifier in Java, as well as some features that will help you understand key programming concepts.

What every programmer should know about the Static modifier in Java

In this section, we'll look at the basics of using static methods, fields, and classes. Let's start with the variables.
  1. You cannot access non-static members of a class within a static context, such as a method or block. Compiling the code below will result in an error:

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

    This is one of the most common mistakes made by Java programmers, especially newbies. Since the method mainis static, but the variable countis not, in this case the method printlninside the method mainwill throw “Compile time error”.

  2. Unlike local variables, static fields and methods are NOT thread-safe in Java. In practice, this is one of the most common causes of problems related to the security of multithreaded programming. Considering that each instance of a class has the same copy of a static variable, such a variable needs to be protected—“locked” by the class. Therefore, when using static variables, make sure they are properly synchronized to avoid problems such as race conditions.

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

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

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

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

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

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

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

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

  7. It's useful to know that static methods are bound at compile time, as opposed to binding virtual or non-static methods, which are bound at runtime on the real object. Therefore, static methods cannot be overridden in Java because runtime polymorphism does not apply to them. This is an important limitation to consider when declaring a method static. This makes sense only when there is no possibility or need to override such a method by inheritor classes. Factory methods and utility methods are good examples of using the static modifier. Joshua Bloch outlined several advantages of using a static factory method over a constructor in his book Effective Java , which is required reading for every programmer of the language.

  8. An important property of a static block is initialization. Static fields or variables are initialized after the class is loaded into memory. The initialization order is from top to bottom, in the same order as they are described in the Java class source file. Since static fields are initialized in a thread-safe manner, this property is also used to implement the Singleton. If you don't use a list Enumlike Singleton, for one reason or another, then there is a good alternative for you. But in this case, it is necessary to take into account that this is not “lazy” initialization. This means that the static field will be initialized BEFORE anyone “asks” for it. If the object is resource-intensive or rarely used, then initializing it in a static block will not work in your favor.

  9. During serialization, just like transientvariables, static fields are not serialized. Indeed, if you save any data in a static field, then after deserialization the new object will contain its primary (default) value, for example, if the static field was a variable of type int, then its value after deserialization will be zero, if the type floatis 0.0, if type Objectnull. Honestly, this is one of the most frequently asked questions regarding serialization in Java interviews. Don't store the most important data about an object in a static field!

  10. And finally, let's talk about static import. This modifier has much in common with the standard operator import, but unlike it, it allows you to import one or all static members of a class. When importing static methods, they can be accessed as if they were defined in the same class, similarly when importing fields, we can access them without specifying the class name. This feature was introduced in Java version 1.5, and when used properly, improves the readability of the code. This construction is most often found in JUnit tests , because Almost all test developers use static importassert methods, for example, assertEquals()and their overloaded duplicates. If nothing is clear, welcome for additional information .

That's all. Every programmer must know all of the above points about the static modifier in Java . This article covered basic information about static variables, fields, methods, initialization blocks and imports. Including some important properties, knowledge of which is critical when writing and understanding programs in Java. I hope that every developer will perfect their skills in using static concepts because... This is very important for serious programming."
Comments
  • Popular
  • New
  • Old
You must be signed in to leave a comment
This page doesn't have any comments yet