[Java] static keyword application and analysis

1. The purpose of the static keyword

There is such a passage on page P86 of "Java Programming Thought":

"A static method is a method without this. You cannot call a non-static method inside a static method, and vice versa. And you can call the static method only through the class itself without creating any objects. This is actually The main purpose of the static method."

Although this passage only illustrates the special features of the static method, you can see the basic function of the static keyword. In short, a one-sentence description is:

It is convenient to call (method/variable) without creating an object.

Obviously, the method or variable modified by the static keyword does not need to depend on the object for access, as long as the class is loaded, it can be accessed through the class name.

Static can be used to modify the member methods and member variables of a class. In addition, you can write static code blocks to optimize program performance.

1) static method

Static methods are generally called static methods. Because static methods do not depend on any object to be accessed, there is no this for static methods, because it is not attached to any object. Since there is no object, it can’t be mentioned. this out. And because of this feature, non-static member variables and non-static member methods of the class cannot be accessed in static methods, because non-static member methods/variables must rely on specific objects to be able to be called.

But it should be noted that although non-static member methods and non-static member variables cannot be accessed in static methods, static member methods/variables can be accessed in non-static member methods.

Insert picture description here

2) static variables

Static variables are also called static variables. The difference between static variables and non-static variables is that static variables are shared by all objects and have only one copy in memory, which will be initialized if and only when the class is first loaded. Non-static variables are owned by the object and are initialized when the object is created. There are multiple copies, and the copies owned by each object do not affect each other.

The initialization order of static member variables is initialized in the order defined.

3) static code block

Another key function of the static keyword is to form static code blocks to optimize program performance. The static block can be placed anywhere in the class, and there can be multiple static blocks in the class. When the class is first loaded, each static block will be executed in the order of the static block, and it will only be executed once.

Summary of static code block features:

  • When this class is used for the first time, the static code block is executed only once;
  • Static content always takes precedence over non-static content, so static code blocks are executed before construction methods;
  • Typical use of static code blocks: to assign values ​​to static member variables at once.

Why the static block can be used to optimize program performance is because of its characteristics: it will only be executed once when the class is loaded. Let's look at an example:

class Person{
    
    
    private Date birthDate;
     
    public Person(Date birthDate) {
    
    
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
    
    
        Date startDate = Date.valueOf("1946");
        Date endDate = Date.valueOf("1964");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

isBornBoomer is used to determine whether this person was born between 1946 and 1964, and every time isBornBoomer is called, two objects, startDate and birthDate, are generated, resulting in a waste of space. It would be more efficient if changed to this:

class Person{
    
    
    private Date birthDate;
    private static Date startDate,endDate;
    static{
    
    
        startDate = Date.valueOf("1946");
        endDate = Date.valueOf("1964");
    }
     
    public Person(Date birthDate) {
    
    
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
    
    
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

Therefore, in many cases, some initialization operations that only need to be performed once are placed in the static code block.

4) The difference between static variables and ordinary member variables

There are four main differences between static variables and ordinary member variables:

Difference 1: Different belonging. Static variables belong to a class, not just to any object; ordinary member variables belong to an object

Difference 2: The storage area is different. Static variables are located in the method area; ordinary member variables are located in the heap area.

Difference 3: The life cycle is different. The life cycle of a static variable is the same as the life cycle of a class; the life cycle of an ordinary member variable and the object to which it belongs is the same.

Difference 4: When the object is serialized (Serializable), static variables will be excluded (because static variables belong to the class, not to the object)

5) What does static and final mean together

Static final is used to modify member variables and member methods, which can be simply understood as "global constants"!

   对于变量,表示一旦给值就不可修改,并且通过类名可以访问。

For methods, it means that it cannot be overridden and can be accessed directly through the class name.

Pay special attention to a problem:

For instance constants modified by static and final, the instance itself cannot be changed, but for instance variables of some container types (for example, ArrayList, HashMap), the container variable itself cannot be changed, but the objects stored in the container can be modified. This is used a lot in programming.

The misunderstanding of the static keyword

1. Will the static keyword change the access rights of members in the class?

Some beginner friends will confuse the function of static keyword in java with static keyword in C/C++. There is only one thing to remember here: unlike static in C/C++, the static keyword in Java does not affect the scope of variables or methods. In Java, the only keywords that can affect access permissions are private, public, and protected (including package access permissions). Look at the following example to understand:

2. Can you access static member variables through this?

Although there is no this for static methods, can static member variables be accessed through this in non-static methods? First look at the following example, what is the output of this code?

public class Main {
    
      
    static int value = 33;
 
    public static void main(String[] args) throws Exception{
    
    
        new Main().printValue();
    }
 
    private void printValue(){
    
    
        int value = 3;
        System.out.println(this.value);
    }
}

This mainly examines the understanding of the team this and static. What does this stand for? this represents the current object, then if printValue is called through new Main(), the current object is the object generated through new Main(). The static variable is enjoyed by the object, so the value of this.value in printValue is undoubtedly 33. The value inside the printValue method is a local variable, it is impossible to associate with this at all, so the output result is 33. Always remember one thing here: Although static member variables are independent of objects, it does not mean that they cannot be accessed through objects. All static methods and static variables can be accessed through objects (as long as the access permissions are sufficient).

3. Can static act on local variables?

In C/C++ static can scope local variables, but remember in Java: static is not allowed to modify local variables. Don't ask why, this is the rule of Java syntax.

3. Common written interview questions

Listed below are some questions about static keywords that are frequently encountered in the interview written test, for reference only, please leave a message below if you have anything to add.

1. What is the output of the following code?

public class Test extends Base{
    
    
 
    static{
    
    
        System.out.println("test static");
    }
     
    public Test(){
    
    
        System.out.println("test constructor");
    }
     
    public static void main(String[] args) {
    
    
        new Test();
    }
}
 
class Base{
    
    
     
    static{
    
    
        System.out.println("base static");
    }
     
    public Base(){
    
    
        System.out.println("base constructor");
    }
}

Output:

base static
test static
base constructor
test constructor

As for why this is the result, let’s not discuss it first. Let’s first think about the specific execution process of this code. At the beginning of execution, we must first find the main method, because the main method is the entry point of the program, but before the main method is executed, you must The Test class is loaded first, and when the Test class is loaded, it is found that the Test class inherits from the Base class, so it will go to load the Base class first. When the Base class is loaded, a static block is found and the static block is executed. After the Base class is loaded, continue to load the Test class, and then find that there is a static block in the Test class, and execute the static block. After loading the required classes, the main method is executed. When executing new Test() in the main method, it will call the constructor of the parent class first, and then call its own constructor. Therefore, the above output result appears.

2. What is the output of this code?

public class Test {
    
    
    Person person = new Person("Test");
    static{
    
    
        System.out.println("test static");
    }
     
    public Test() {
    
    
        System.out.println("test constructor");
    }
     
    public static void main(String[] args) {
    
    
        new MyClass();
    }
}
 
class Person{
    
    
    static{
    
    
        System.out.println("person static");
    }
    public Person(String str) {
    
    
        System.out.println("person "+str);
    }
}
 
 
class MyClass extends Test {
    
    
    Person person = new Person("MyClass");
    static{
    
    
        System.out.println("myclass static");
    }
     
    public MyClass() {
    
    
        System.out.println("myclass constructor");
    }
}

Output:

test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

Similarly, let's think about the specific execution process of this code. Load the Test class first, so the static block in the Test class will be executed. Then execute new MyClass(), and the MyClass class has not been loaded yet, so the MyClass class needs to be loaded. When loading the MyClass class, it is found that the MyClass class inherits from the Test class, but because the Test class has been loaded, only the MyClass class needs to be loaded, and the static block in the MyClass class will be executed. After loading, the object is generated through the constructor. When generating an object, you must first initialize the member variables of the parent class, so Person person = new Person() in Test will be executed, and the Person class has not been loaded yet, so the Person class will be loaded and executed in the Person class. The static block of the parent class is executed, and the initialization of the parent class is completed, and then it initializes itself, so it will execute Person person = new Person() in MyClass, and finally execute the constructor of MyClass.

3. What is the output of this code?

public class Test {
    
    
     
    static{
    
    
        System.out.println("test static 1");
    }
    public static void main(String[] args) {
    
    
         
    }
     
    static{
    
    
        System.out.println("test static 2");
    }
}

Output:

test static 1
test static 2

Although there is no statement in the main method, it will still output because the reasons have been described above. In addition, the static block can appear anywhere in the class (as long as it is not inside the method, remember that no method will work), and the execution is executed in the order of the static block.

To be seen:
https://zhuanlan.zhihu.com/p/70110497
https://www.cnblogs.com/dolphin0520/p/10651845.html

Guess you like

Origin blog.csdn.net/qq_30885821/article/details/109329277