Static is often used in our daily life of the keyword, is a very important keyword in Java, the static can modify variables, methods, do the static block of code, static guide package, etc., let’s to talk about the key word, let’s begin from the basic, from basic usage, and then analyze its principle, optimization, etc.

The static keyword

Static modifiers

The static keyword denotes a concept that is global and static, and the variables it modifies are called static variables.

public class TestStatic {
    
    static int i = 10; // define a static variable I
}
Copy the code

Static variables are also called class variables. Static variables are owned by the class. What does that mean? The static keyword can only be defined in {} of a class, not in any method.

This works even if you drop the static keyword from the method.

Static is owned by a class and calls static modified variables directly. It does not need to manually instantiate the class to make the call

public class TestStatic {

    static int i = 10;

    public static void main(String[] args) { System.out.println(TestStatic.i); }}Copy the code

Here you need to understand the concept of several variables

  • Defined in constructors, code blocks, methodsoutsideAre called instance variables, and the number of copies of instance variables is the same as the number of instances.
  • Defined in methods, constructors, code blocksWithin theVariables of are called local variables;
  • Defined in method parametersIn theThe variables of are called parameters.

Details refer to

Static modifier

Static can modify a method. A method that is static is called a static method

static void sayHello(a){}
Copy the code

Java Programming Minds has a classic description on page P86

Static methods are methods that do not have this. Non-static methods cannot be called from inside static, and vice versa. You can also call static methods from the class itself without creating any objects, which is actually the main purpose of static methods.

A static method is a method that does not have this. You can access a static method without creating an object. Take a look at the code below

In the example above, because staticMethod is static, you can use the class name. Variable name to call.

Therefore, if you want to call a method without creating an object, you can set the method to static. The most common static method we see is the main method, and it should now be clear why the main method must be static. Because the program does not create any objects when it executes the main method, it is only accessed by the class name.

Considerations for the static modifier

  • So the first one is the most common one, you don’t have to create an object, you just create itClass name. Variable nameAccessible;
  • Static modified methods cannot call non-static methods from within;

  • Static static methods can be called from within non-static methods.

Static decorates a code block

The static keyword can be used to modify blocks of code that use {} blocks. One is static {} static code blocks. A code block that is static is called a static code block. Static code blocks can be placed anywhere in a class. A class can have multiple static blocks. When the class is first loaded, each static modified block is executed in the same order as the static blocks. We’ll talk a little bit about the loading order of the code blocks. Here is an example of a static code block

Static code blocks can be used to optimize the order of program execution because of their nature: they are executed only once when the class is loaded.

Static is used as a static inner class

There are fewer use scenarios for inner classes, but there are some more useful ones. Before we look at static inner classes, let’s look at the classification of inner classes

  • Ordinary inner class
  • Local inner class
  • Static inner class
  • Anonymous inner class

A static inner class is a static inner class. A static inner class may contain static or non-static members, but a non-static inner class may not declare static members.

Static inner class has many functions. Since the creation of an instance of a non-static inner class requires a reference to an external class object, the creation of a non-static inner class object must rely on an instance of an external class. Instance creation of static inner classes relies only on external classes;

And because a non-static inner class object holds a reference to an outer class object, a non-static inner class can access a non-static member of the outer class. A static inner class can access only static members of an external class.

  • The inner class needs to detach from the outer class object to create an instance
  • Avoid memory overflow during inner class usage
public class ClassDemo {
  
    private int a = 10;
    private static int b = 20;

    static class StaticClass{
        public static int c = 30;
        public int d = 40;
      
        public static void print(a){
            // Static inner class cannot access external class instance members
            //System.out.println(a);
     
            // Static inner classes can access only the members of the outer class
            System.out.println("b = "+b);
            
        }
      
        public void print01(a){
            // A method in a static inner class that calls an instance method of a static inner class is an instance method in an external class that calls a static inner class
            StaticClass sc = newStaticClass(); sc.print(); }}}Copy the code

Static guide package

If you have noticed this, for example, when you use a java.util utility class, you need to import the java.util package in order to use the utility classes inside it, as follows

However, there is another way to import static packages. Static imports are used to import static methods or variables from a class or package.

import static java.lang.Integer.*;

public class StaticTest {

    public static void main(String[] args) {
        System.out.println(MAX_VALUE);
        System.out.println(toHexString(111)); }}Copy the code

Static advanced knowledge

Let’s go static. Let’s go static. Let’s go static

About the class of static

Static attributes and methods belong to classes and do not belong to any object. They are all called by class names. Property/method names, while instance variables and local variables belong to concrete object instances.

Static modifies where a variable is stored

First, take a look at the different storage areas of the JVM.

  • Virtual machine stack: The Java virtual machine stack is the data area that is private to the thread. The Java virtual machine stack has the same life cycle as the thread. The virtual machine stack is also the location where local variables are stored. Method creates a stack frame in the virtual machine stack during execution.

  • Local method stack: The local method stack is also the data area that is private to the thread. The local method stack stores the area that is mainly stored in Java for methods decorated with native keywords

  • Program counter: The program counter is also the thread’s private data area. This area is used to store the instruction address of the thread, and is used to determine the branch, loop, jump, exception, thread switch, and recovery functions of the thread, all of which are done by the program counter.

  • Method area: The method area is an area of memory shared by individual threads that stores data such as virtual-loaded class information, constants, static variables, and just-in-time compiler compiled code. That is, static modified variables are stored in the method area

  • Heap: The heap is the data area shared by threads. The heap is the largest storage area in the JVM. All object instances, including instance variables, are allocated on the heap accordingly.

Static The life cycle of a variable

Static variables have the same life cycle as classes. They are created when the class is loaded and destroyed when the class is destroyed. A normal member variable has the same life cycle as the one to which it belongs.

The static serialization

As we know, the purpose of serialization is to convert A Java object into a sequence of bytes. Object to an ordered byte stream so that it can be transferred over the network or saved in a local file.

Variables declared static and TRANSIENT cannot be serialized because static variables are stored in the method area and are serialized only in heap memory. The transient keyword prevents the object from being serialized.

Class loading order

We mentioned the concept of class loading order earlier. Static modified variables and static code blocks are initialized before being used. Classes are initialized in the following order

Load static fields of the parent class -> Static code blocks of the parent class -> Subclass static fields -> Subclass static code blocks -> Superclass member variables (non-static fields)

-> Parent non-static code block -> Parent constructor -> Subclass member variable -> Subclass member variable -> Subclass non-static code block -> Subclass constructor

Static is often used for log printing

The static keyword is often used to print logs during development. Here is a line of code you should see frequently

private static final Logger LOGGER = LogFactory.getLoggger(StaticTest.class);
Copy the code

However, you can print logs by leaving static and final out

private final Logger LOGGER = LogFactory.getLoggger(StaticTest.class);
private Logger LOGGER = LogFactory.getLoggger(StaticTest.class);
Copy the code

But there are problems with this way of printing logs

Each StaticTest instantiation object will have a LOGGER. If you create 1,000 StaticTest objects, you will have 1,000 more loggers, which is a waste of resources, so LOGGER objects are usually declared static, In this way, you can reduce the footprint of memory resources.

Static is often used as a singleton

Since the singleton pattern means that there is only one copy of it for different classes, static can match the singleton pattern exactly.

The following is a classic scenario for implementing the singleton pattern with a double checklock

public class Singleton {
  
    private static volatile Singleton singleton;
 
    private Singleton(a) {}
 
    public static Singleton getInstance(a) {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = newSingleton(); }}}returnsingleton; }}Copy the code

Let’s make a brief description of the above code

Use static to ensure that singleton variables are static, volatile to ensure visibility of Singleton variables, and private constructors to ensure that singleton cannot be instantiated by new.

If Singleton is empty, the Singleton class will be locked. If Singleton is empty, the Singletion class will be locked

If thread T1 executes until Singleton == NULL and determines that the object is null, then the thread transfers the execution authority to T2, which determines that the object is null and locks the Singleton class object to proceed with the following judgment and instantiation process. If the second judgment is not made, t1 will also be instantiated after the first nullation, and multiple objects will still be created.

Class constructor is static

Static class constructor: static class constructor: static class constructor: static class constructor: static

  • The simplest and most memorable rule for static is to have no this reference. In the constructor of a class, there is an implicit this binding, because the constructor is bound to the class. In this sense, the constructor is not static.
  • From a class method point of view, becauseClass. Method nameYou don’t need to create a new object to access it, so the constructor is not static from this point of view
  • From the perspective of JVM directives, let’s look at an example
public class StaticTest {

    public StaticTest(a){}

    public static void test(a){}public static void main(String[] args) {
        StaticTest.test();
        StaticTest staticTest = newStaticTest(); }}Copy the code

Let’s use Javap -c to generate the bytecode for StaticTest

public class test.StaticTest {
  public test.StaticTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void test();
    Code:
       0: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #2                  // Method test:()V
       3: new           #3                  // class test/StaticTest
       6: dup
       7: invokespecial #4                  // Method "<init>":()V
      10: astore_1
      11: return
}

Copy the code

We found that when call the static method is to use invokestatic instructions, we call the new object invokespecial instruction, and in the JVM specification docs.oracle.com/javase/spec… When it comes to

From this perspective, an invokestatic instruction is an instruction that specifically executes static methods; Invokespecial is an instruction specifically used to execute the instance method; In this sense, the constructor is not static.