Four uses of static keyword

Posted by mark_nsx on Wed, 02 Mar 2022 11:31:26 +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
     * Name:zhangsan, Age:10
     * Name:lisi, Age:12
     *///~
}

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 */

    /**Output
     * Name:zhangsan, Age:12
     * Name:lisi, Age:12
     *///~
}

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 attributes, we will generally adopt 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);
    }
    /**Output
     * Id:1, Name:zhangsan, Age:10
     * Id:2, Name:lisi, Age:12
     *///~
}

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:

package com.dotgua.study;

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");
    }
    /**Output
     * static Member book2 member variable initialization
     * static Member book4 member variable initialization
     * book1 Member variable initialization
     * book3 Member variable initialization
     * p1 initialization
     *///~
}

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.

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");
    }
    /**Output
     * static Member book2 member variable initialization
     * static Member book4 member variable initialization
     * static Modified funStatic method
     * ***************
     * book1 Member variable initialization
     * book3 Member variable initialization
     * p1 initialization
     *///~
}

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 */
package com.dotgua.study;

public class PrintHelper {

    public static void print(Object o){
        System.out.println(o);
    }
}
/* App.java file */

import static com.dotgua.study.PrintHelper.*;

public class App 
{
    public static void main( String[] args )
    {
        print("Hello World!");
    }
    /**Output
     * 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, which can be called directly by "class name. Method name", which is often 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. The usage of static package guide is to directly import the methods of the class into the current class, so that the class methods can be called directly by using the "method name", which is more convenient.

Topics: Java IntelliJ IDEA