Four usages of Static keyword in Java

Posted by Mce on Wed, 09 Mar 2022 07:29:53 +0100

Among the keywords of java, static and final are two keywords that we must master. Different from other keywords, they have a variety of uses, and when used in a certain environment, they can improve the running performance of the program and optimize the structure of the program. Let's first learn about the static keyword and its usage.

static keyword

1. Modify member variables

In our daily use, the most commonly used function of static is to modify the properties and methods of the class and make them become the member properties and methods of the class. We usually call the members modified with static as class members or static members. This sentence sounds a little strange. In fact, this is relative to the properties and methods of the object. Let's take a look at the following example: (the program is too bloated to avoid, and access control is ignored for the time being)

public class Person {
    String name;
    int age;
    
    public String toString() {
        return "Name:" + name + ", Age:" + age;
    }
    
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "zhangsan";
        p1.age = 10;
        Person p2 = new Person();
        p2.name = "lisi";
        p2.age = 12;
        System.out.println(p1);
        System.out.println(p2);
    }
}

Output result:

We are very familiar with the above code. Each object constructed according to Person exists independently and saves its own independent member variables, which will not affect each other. Their schematic diagram in memory is as follows:

As can be seen from the above figure, the objects referenced by p1 and p2 variables are stored in different addresses of the heap area in memory, so they will not interfere with each other. But in fact, we have omitted some important information. I believe everyone will think that the member properties of objects are here and saved by each object. What about their methods? In fact, no matter how many objects a class creates, their methods are the same:

From the above figure, we can see that the methods of two Person objects actually point to the same method definition. This method is defined as an invariant area (divided by jvm) in memory, which is temporarily called static storage area. This storage area not only stores the definition of methods, but also stores various definitions. When we generate objects through new, we will create objects according to the definition of classes defined here. Multiple objects only correspond to the same method. Here is a convincing reason for us, that is, no matter how many objects, their methods are always the same. Although the final output will be different, the methods will always operate according to our expected results, that is, if different objects call the same method, the results will be different.

We know that the static keyword can modify member variables and methods to make them belong to the class rather than the object. For example, if we modify the age attribute of Person with static, what will be the result? Take the following example:

public class Person {
    String name;
    static int age;
    
    /* The rest of the code remains unchanged */
}

The output result is:

We found that the result changed a little. When assigning a value to the age attribute of p2, it interfered with the age attribute of p1. Why? Let's take a look at their schematic in memory:

We found that after adding the static keyword to the age attribute, the Person object no longer has the age attribute. The age attribute will be uniformly managed by the Person class, that is, multiple Person objects will only correspond to one age attribute. If an object changes the age attribute, other objects will be affected. We can see that the age and toString() methods at this time are managed by the class.

Although we see that static allows objects to share attributes, we rarely use it in practice, and we don't recommend it. This makes the property difficult to control because it can be changed anywhere. If we want to share properties, we usually use other methods

public class Person {
    private static int count = 0;
    int id;
    String name;
    int age;
    
    public Person() {
        id = ++count;
    }
    
    public String toString() {
        return "Id:" + id + ", Name:" + name + ", Age:" + age;
    }
    
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "zhangsan";
        p1.age = 10;
        Person p2 = new Person();
        p2.name = "lisi";
        p2.age = 12;
        System.out.println(p1);
        System.out.println(p2);
    }
}

The output result is

The above code plays the role of creating a unique id for the Person object and recording the total number. Count is modified by static and is the member attribute of the Person class. Each time a Person object is created, the attribute will be increased by 1 and then assigned to the id attribute of the object. In this way, the count attribute records the total number of Person objects created. Because count uses the private modification, Therefore, it cannot be changed at will from outside the class.

2. Methods of modifying members

Another function of static is to modify member methods. Compared with modifying member attributes, modifying Member methods does not change much in the storage of data, because we can see from the above that methods are originally stored in the definition of classes. The most important function of static modifying Member method is to use "class name. Method name" to operate the method, avoiding the cumbersome and resource consumption of new object first. We may often see its use in the help class:

public class PrintHelper {

    public static void print(Object o){
        System.out.println(o);
    }
    
    public static void main(String[] args) {
        PrintHelper.print("Hello world");
    }
}

The above is an example (not very practical at present), but we can see its role, which makes the static modified method become the method of the class. When using it, it can be used conveniently through "class name. Method name", which is equivalent to defining a global function (just import the package where the class is located). However, it also has limitations. In a static modified class, non static modified member variables and methods cannot be used, which is easy to understand, because the static modified method belongs to the class. If you directly use the member variables of the object, it will be at a loss (I don't know which object attribute to use).

3. Static block

When explaining the third usage of static keyword, it is necessary to re sort out the initialization process of an object. Take the following code as an example:

class Book{
    public Book(String msg) {
        System.out.println(msg);
    }
}

public class Person {

    Book book1 = new Book("book1 Member variable initialization");
    static Book book2 = new Book("static member book2 Member variable initialization");
    
    public Person(String msg) {
        System.out.println(msg);
    }
    
    Book book3 = new Book("book3 Member variable initialization");
    static Book book4 = new Book("static member book4 Member variable initialization");
    
    public static void main(String[] args) {
        Person p1 = new Person("p1 initialization");
    }
}

The output result is:

In the above example, four Book member variables are combined in the person class, two are ordinary members and two are static modified class members. We can see that when we new a Person object, the static modified member variable is initialized first, followed by an ordinary member, and finally calls the Person class construction method to complete the initialization. In other words, when creating an object, members decorated with static will be initialized first, and we can also see that if there are multiple members decorated with static, they will be initialized according to their sequence.

In fact, members decorated with static can be initialized earlier. Please see the following example:

class Book{
    public Book(String msg) {
        System.out.println(msg);
    }
}

public class Person {

    Book book1 = new Book("book1 Member variable initialization");
    static Book book2 = new Book("static member book2 Member variable initialization");
    
    public Person(String msg) {
        System.out.println(msg);
    }
    
    Book book3 = new Book("book3 Member variable initialization");
    static Book book4 = new Book("static member book4 Initializing member variables");
    
    public static void funStatic() {
        System.out.println("static Embellished funStatic method");
    }
    
    public static void main(String[] args) {
        Person.funStatic();
        System.out.println("****************");
        Person p1 = new Person("p1 initialization");
    }
}

The output result is:

In the above example, we can find two interesting places. The first is that when we call a class method through a class without creating an object, although the method does not use any class members, the class members are initialized before the method call. This shows that when we use a class for the first time, the member initialization of the class will be triggered. The second is that when we use class methods to initialize the members of a class and then new the objects of the class, the static modified class members are not initialized again, which shows that the static modified class members only need to be initialized once during the running process of the program and will not be initialized many times.

After reviewing the initialization of objects, the third function of static is very simple. That is, when we initialize the members modified by static, we can put them in a block statement starting with static and wrapped in curly braces:

class Book{
    public Book(String msg) {
        System.out.println(msg);
    }
}

public class Person {

    Book book1 = new Book("book1 Member variable initialization");
    static Book book2;
    
    static {
        book2 = new Book("static member book2 Member variable initialization");
        book4 = new Book("static member book4 Member variable initialization");
    }
    
    public Person(String msg) {
        System.out.println(msg);
    }
    
    Book book3 = new Book("book3 Member variable initialization");
    static Book book4;
    
    public static void funStatic() {
        System.out.println("static Embellished funStatic method");
    }
    
    public static void main(String[] args) {
        Person.funStatic();
        System.out.println("****************");
        Person p1 = new Person("p1 initialization");
    }
}

The output result is:

We have slightly modified the previous example. We can see that there is no difference in the results.

4. Static guide bag

Compared with the above three uses, the fourth use may be understood by fewer people, but in fact, it is very simple and more convenient to call class methods. Take the example of "PrintHelper" above as an example. Make a slight change to make it convenient for us to use the static guide package:

/* PrintHelper.java file */
public class PrintHelper {
package com.yuteng.study;
    public static void print(Object o){
        System.out.println(o);
    }
}
/* App.java file */import static com.yuteng.study.PrintHelper.*;

public class App 
{
    public static void main( String[] args )
    {
        print("Hello World!");
    }
}

The output result is: Hello World!
The above code comes from two java files. The PrintHelper is very simple and contains a static method for printing. And on app In the java file, we first import the PrintHelper class. Here, when importing, we use the static keyword, and add ". *" at the end of the imported class. Its function is to directly import all class methods in the PrintHelper class. Unlike non static import, after static import package is adopted, there is no need to use the method of "class name. Method name" to call class methods without conflicting with the method name of the current class. Instead, the method name can be directly used to call class methods, just like the method of the class itself.

summary
static is a very important keyword in java, and its usage is also very rich. There are four main uses:

  1. It is used to modify the member variable and change it into a member of the class, so as to realize the sharing of all objects for the member;
  2. It is used to modify member methods and turn them into class methods. You can directly * * call them in the way of "class name. Method name". * * is commonly used in tool classes;
  3. Static block usage, which initializes multiple class members together, makes the program more regular. It is very important to understand the initialization process of objects;
  4. Static guided package usage: directly import the methods of the class into the current class, so that the class methods can be called directly using the "method name", which is more convenient.

Topics: Java