JavaRush /Java Blog /Random EN /10 Notes About the Static Modifier in Java
Author
Pavlo Plynko
Java-разработчик at CodeGym

10 Notes About the Static Modifier in Java

Published in the Random EN group
The static modifier in Java is directly related to the class. If the field is static, then it belongs to the class, if the method is static, it is similar: it belongs to the class. Based on this, you can refer to 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 About the Static Modifier in Java - 1Before getting into the notes, let's remember (or maybe learn) what is static and what can be static in Java. Static is a modifier applied to a field, block, method, or inner class. This modifier indicates the binding of the subject to the current class.

Static fields

When we designate a class-level variable, we indicate that this value refers to a class. If this is not done, then the value of the variable will be bound to the object created by this class. What does it mean? 10 Notes About the Static Modifier in Java - 2And the fact that if the variable is not static, then each new object of this class will have its own value for this variable, 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);
We will get the output:

Orange car - 100
Blue car - 85
As you can see, each object has its own variable, which changes 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, and every time we change it. Static variables are usually accessed not by object reference - orangeCar.km, but by class name - Car.km

static block

There are two initialization blocks - normal and static. The block is designed to initialize internal variables. If the block is ordinary, then the internal variables of the object are initialized with it, if it is static, respectively, they are assigned static variables (that is, class variables). An 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, not to an object. An important property of a static method is that it can only access static variables/methods. As an example, let's consider a class that we will have 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 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 bound to the outer class, and if the outer class is inherited by another class, then this one will not be inherited. At the same time, this class can be inherited, just as it can be inherited from any other class and implement an interface. In essence, a static nested class is no different from any other inner class, except that its object does not contain a reference to the object of the outer class that created it. However, this makes a static class the most similar to a regular non-nested class, the only difference being 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. An 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 an 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 this class. Of course, access modifiers should be considered. For example, fields privateare only accessible within the class in which they are declared. Fields protectedare available to all classes inside the package ( package ), as well as to all descendant classes outside the package. For more information, see 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 a call of the form Counter.increment(). No need to instantiate the classCounterto access a static field or method. This is the fundamental difference between static and NOT static objects (class members). Let me remind you once again that static members of a class directly belong to the class, and 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 will look at the fundamental aspects of using the static modifier in Java, as well as some of the features that will help you understand key programming concepts. 10 Notes About the Static Modifier in Java - 3

What Every Programmer Should Know About the Static Modifier in Java

In this section, we will cover the main points of using static methods, fields and classes. Let's start with variables.
  1. You can NOT access non-static members of a class, inside a static context, like 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 and the variable countis not, in this case the method printlninside the method mainwill throw a “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 reasons for the emergence of problems related to the safety of multithreaded programming. Considering that each class instance 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. Static methods have an advantage in application, because. there is no need to create a new object every time to access such methods. A static method can be called using the class type in which these methods are declared. That is why such methods are the best suited as factory methods ( factory), and utility methods ( utility). A class java.lang.Mathis a great example where almost all methods are static, which is the same reason Java utility classes are finalized ( final).

  4. Another important point is that you can NOT override ( Override) static methods. If you declare the same method in a derived class ( subclass), i.e. method with the same name and signature, you will only "hide" the superclass method ( superclass) instead of overriding it. This phenomenon is known as method hiding ( hiding methods). This means that when accessing a static method that is declared in both the parent and child classes, the method will always be called at compile time based on the type of the variable. Unlike overriding, such methods will not be executed while the program is running. Consider an example:

    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);
      }}

    Console output:

    Inside parent class/static method

    The code clearly demonstrates that despite the fact that the object is of type Car, a static method from the class was called Vehicle, because the method was called at compile time. And note that there was no compile-time error!

  5. You can also declare a class static, except for top-level classes. Such classes are known as "nested static classes" ( nested static class). They are useful for presenting improved links. A prime example of a nested static class is HashMap.Entry, which provides a data structure inside HashMap. It's worth noting that just like any other inner class, nested classes are in a separate .class file. So if you declared five nested classes in your main class, you will have 6 .class files. Another use case is declaring your own comparator ( Comparator), such as the age comparator ( AgeComparator) in the employee class ( Employee).

  6. The static modifier can also be declared in a static block, better known as a "Static Initialization Block" ( Static initializer block), which will be executed during class loading. If you do not declare such a block, then Java will collect all the static fields into one list and execute it during class loading. However, a static block can NOT throw caught exceptions, but it can throw uncaught ones. In such a case, an "Exception Initializer Error" will occur. In practice, any exception thrown during runtime and initialization of static fields will be wrapped by Java in this error. This is also the most common cause of the "No Class Def Found Error" error. the class was not in memory at the time it was accessed.

  7. It is useful to know that static methods are bound at compile time, as opposed to the binding of virtual or non-static methods, which are bound at run time on the real object. Therefore, static methods cannot be overridden in Java, because run-time polymorphism does not apply to them. This is an important limitation to keep in mind when declaring a method as static. This makes sense only when it is not possible or necessary to override such a method by descendant classes. Factory methods and utility methods are good examples of the static modifier. Joshua Bloch highlighted several advantages of using a static factory method over a constructor in Effective Java”, which is mandatory reading for every programmer of this 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. Because static fields are initialized in a thread-safe manner, this property is also used to implement the Singleton. If you're not using a list Enumlike Singleton, for one reason or another, then there's a good alternative for you. But in this case, it is necessary to take into account that this is not a "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 play 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 (by default) value, for example, if the static field was a variable of type , then its value after deserialization will be zero, if the type is 0.0 int, floatif type Object- null. To be honest, this is one of the most commonly asked serialization questions in Java interviews. Do not 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 allows you to import one or all of the static members of the 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 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 construct is most often found in JUnit tests , because almost all test developers use static importfor assert methods, for example, assertEquals()and for their overloaded counterparts. If nothing is clear - welcome for more information .

That's all. All of the above points about the static modifier in Java should be known to every programmer. This article covered basic information about static variables, fields, methods, initialization blocks, and imports. Including some important properties, the knowledge of which is critical when writing and understanding Java programs. I hope that every developer will perfect their skills in using static concepts to perfection. this is very important for serious programming."
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION