static keyword

The static keyword is used to create class-level variables and methods.
Static means that the memory space determined when the class is loaded does not change.
Static variables and methods can be used without creating an object like this:

  • ClassName.staticVariable
  • ClassName.staticMethod()

The main method is a static method.
If you run java Test at the command prompt, The class loader loads Test.class into memory.
The JVM then calls the main method of the Test class loaded into memory.

To run a Java program, the class must first be loaded into memory.
When a class is loaded into memory, space is allocated for static variables.
The memory space to which a static variable is allocated does not change until the end of the program.

The memory space to which an object is allocated differs from the memory space in which the class is loaded.
The space to which objects are allocated is the heap memory area of the JVM.
Every time new is run, heap memory is allocated for the object's instance variables.

You can not use instance variables in static methods.
It does not make sense to refer to the properties of an object that it can not create.
If you add a main method to the student class and implement it like this, you will get a compile error.

public static void main(String[] args) {
    absentNum++;
}

Conversely, using static variables or static methods in instance methods is not a problem.
Suppose a student is fined if he / she is absent, late or late.
The fine is $ 3 for absences, and $ 1 for late or early retirement.
The fine must be put in a penalty box.
A penalty box is only one and all students share.
And that it is not a property that distinguishes students from students.
How do I implement a penalty box in code?
A approach is to make the fines a static variable that all student objects share.

public class Student {
    static int penaltyBox;

    public void absent() {
        this.absent++;
        Student.penaltyBox += 3;
    }
    //..Omit
}    

The following is an example of a static variable that stores the total number of users.

package net.java_school.user;

public class User {

    public static int totalUser;
    private String id;
    
    public User(String id) {
        this.id = id;
        total++;
    }

    public static void main(String[] args) {
        User user1 = new User("hong1440");
        User user2 = new User("im1562");
        User user3 = new User("jang1692");
        
        System.out.println("Total Users : " + User.totalUser);
    }

}
C:\ Command Prompt
C:\..>java net.java_school.user.User
Total Users : 3

Singleton pattern

The design pattern used when only one object needs to be created is a singleton pattern.
Suppose there is only one dinner table at home.
It is not an ideal home if you have several dinner tables and eat each one.
The design of a dinner table object using a singleton pattern is as follows.

package net.java_school.home;

public class DinnerTable {

    private static DinnerTable instance = new DinnerTable();
    
    public static DinnerTable getInstance() {
        return instance;
    }
    
    private DinnerTable() {}
    
    //..Omit
  
}

A DinnerTable object is created in the heap memory to initialize a static variable, instance of the DinnerTable, and a reference to the generated object is assigned to the instance static variable.
This reference value can only be obtained through the public getInstance() method.
Set the access modifier of the single constructor to private to prevent the constructor from being called from outside.
This implementation will keep the DinnerTable instance as one until the end of the program.

Initialization Order

Variables are initialized when allocated to memory space.
If there is no initial value, the Boolean type is false, the numeric type is 0, and the reference type is initialized to null.

Instance member variables are initialized when the object is created.

The initialization order is static variables, instance variables, and constructors.

Static variables and static blocks are at the same level.
So the previous one in the code is initialized first.

For instance blocks, the compiler adds the implementation of the instance block to every constructor.
Thus, the instance block is executed before the constructor.

A.java
package net.java_school.classvar;

public class A {

    public A() {
        System.out.println("A() has executed.");//4,9,14
    }
        
}
B.java
package net.java_school.classvar;

public class B {
    private A a = new A();//3,8,13
    
    {
        System.out.println("B instance block has executed.");//5,10,15
    }
    
    static {
        System.out.println("B static block has executed.");//1
    }
    
    private static B b = new B();//2

    private B() {
        System.out.println("B() has executed.");//6,11
    }
    
    public B(int a) {
        System.out.println("B(int) has executed.");//16
    }

    public static void main(String[] args) {
        new B();//7
        new B(1);//12
    }
        
}
C:\ Command Prompt
C:\..>java net.java_school.classvar.B
B static block has executed.
A() has executed.
B instance block has executed.
B() has executed.
A() has executed.
B instance block has executed.
B() has executed.
A() has executed.
B instance block has executed.
B(int) has executed.
References