Understand Java code blocks

Posted by sgtpepper on Fri, 28 Jan 2022 04:22:18 +0100

1, Code block introduction

From: teacher Han Shunping's basic course explanation

1.1 basic introduction

  • Basic introduction
    A coded block, also known as an initialization block, belongs to a member of a class [that is, a part of a class], which is similar to a method. It encapsulates logical statements in the method body and is surrounded by {}. However, unlike a method, it has no method name, no return, no parameters, only the method body, and is not explicitly called through an object or class. Instead, when loading a class, Or implicitly when an object is created.

1.2 basic grammar

  • Basic grammar

[modifier]{
code
};

be careful:

  • Modifier is optional. If you want to write, you can only write static.
    • Static modification is called static code block.
    • Those without static modification are called ordinary code blocks.
  • A logical statement can be any logical statement (input, output, method call, loop, judgment, etc.)
  • ; The number can be written or omitted.

1.3 benefits of code blocks

Benefits and case demonstrations of code blocks:

  • It is equivalent to another form of constructor (a supplementary mechanism to the constructor), which can be initialized.
  • Each time a class object is created, a normal code block is called.
  • Scenario: if there are repeated statements in multiple constructors, they can be extracted into the initialization block to improve the reusability of the code.

Case: codeblock01 java

package com.alan.codeblock;
/**
 * Developer: Zzw
 * Development time: 2021 / 6 / 20 9:39
 * File name: CodeBlock01
 * Development tool: IntelliJ IDEA
 * Project features: getting started with code blocks
 */
public class CodeBlock01 {
    public static void main(String[] args) {
        Movie movie1 = new Movie();
        System.out.println("==========");
        Movie movie2 = new Movie("Uncle pan advised you...");
        System.out.println("==========");
        Movie movie3 = new Movie("trickster,You can't hold it",66);
    }
}

class Movie{
    private String name;
    private double price;

    // Code block
    {
        System.out.println("Foreplay");
        System.out.println("The movie begins");
    }
    public Movie(){
        System.out.println("Movie()...");
    }

    public Movie(String name) {
        System.out.println("Movie(String name)...");
        this.name = name;
    }

    public Movie(String name, double price) {
        System.out.println("Movie(String name, double price)...");
        this.name = name;
        this.price = price;
    }
}

Output:

Foreplay
 The movie begins
Movie()...
==========
Foreplay
 The movie begins
Movie(String name)...
==========
Foreplay
 The movie begins
Movie(String name, double price)...

=>For ordinary code blocks, when creating (new) an object, no matter which constructor is called, the content of the code block will be executed first.

2, Code block usage details

2.1 static code block and class loading

  • Static code block is also called static code block. Its function is to initialize the class, and it will be executed as the class is loaded, and it will only be executed once. If it is a normal code block, it is executed every time an object is created.
    • Static static code blocks can only be placed in classes, independent of other methods.
    • this keyword is not allowed in static methods and static code blocks.
  • When is the class loaded [important]
    • When creating an object instance (new)
    • When a subclass object instance is created, the parent class will also be loaded (load the parent class first)
    • When using static members of a class (static properties, static methods)
    • Use reflection: class forName();
  • Ordinary code blocks are implicitly called when creating object instances. Once created, it will be called once. If you only use the static members of the class, the ordinary code block will not be executed, which has nothing to do with the loading of the class.

Case: codeblockdetail01 java

package com.alan.codeblock;

import org.junit.Test;

/**
 * Developer: Zzw
 * Development time: 11:20, June 20, 2021
 * File name: CodeBlockDetail01
 * Development tool: IntelliJ IDEA
 * Project function: use details of code blocks
 */
public class CodeBlockDetail01 {
    public static void main(String[] args) {
        // Examples of class loading
        // 1. When creating this kind of object
        // Static code blocks are executed only once, when the class is loaded
        Dog dog = new Dog();

        // 2. Create a subclass object instance. The parent class will also be loaded, and the parent class will load the subclass first and then load it
        Son son = new Son();

        // 3. Use static members of the class (static properties and static methods)
        System.out.println("Dog.name: " + Dog.name);
    }
}

class Dog{
    public static String name = "ha-ha";
    {
        System.out.println("Dog Common code block execution...");
    }
    static {
        System.out.println("Dog Static code block execution...");
    }
}

class Father {
    static {
        System.out.println("Laozi's static code block execution...");
    }
}

class Son extends Father {
    public static String name = "Son";

    static {
        System.out.println("Son's static code block execution...");
    }
}

Output:

Dog Static code block execution...
Dog Common code block execution...
Dog Common code block execution...
Laozi's static code block execution...
Son's static code block execution...
Dog.name: ha-ha

Explanation:

  1. Dog dog1 = new Dog();
    Output 1: static code block execution of Dog
    Explanation: create (new) Dog object = > Load of class = > static code block of Dog will be executed
    Output 2: normal code block execution of Dog
    Explanation: the normal code block of creating (new) Dog object = > Dog will be executed
  2. Dog dog2 = new Dog();
    Output: normal code block execution of Dog
    Explanation: create a (new) Dog object = > the normal code block of Dog will be executed. The previous class has been loaded (smart load once), so the static code block will not be executed
  3. Son son = new Son();
    Output 1: Lao Tzu's static code block execution
    Output 2: son's static code block execution
    Explanation: create (new) Son object = > Load of Son class = > Load of father class = > static code block execution of father = > static code block execution of Son
  4. System.out.println("Dog.name: " + Dog.name);
    Output: dog Name: ha ha
    Explanation: the Dog class has been loaded and will not execute the static code block again. If there are no creation objects of 1 and 2, then "Dog.name: ha ha" will be output first

2.2 calling sequence of single class code blocks

When creating an object, the calling order in a class is: (key, difficult)

  1. Call static code block and static attribute initialization
    Note: static code blocks have the same priority as static attribute initialization calls. If multiple static code blocks and static variables are initialized, they will be called in the defined order
  2. Call the initialization of common code blocks and common attributes
    Note: common code blocks and common attribute initialization calls have the same priority. If there are multiple common code blocks and common attribute initialization, they will be called in the defined order
  3. Call construction method

Case: codeblockdetail02 java

package com.alan.codeblock;

/**
 * Developer: Zzw
 * Development time: June 20, 2021 14:31
 * File name: CodeBlockDetail02
 * Development tool: IntelliJ IDEA
 * Project function:
 */
public class CodeBlockDetail02 {
    public static void main(String[] args) {
        Number number = new Number();
    }
}

class Number {
    public Number() {
        System.out.println("Number() constructor ...");
    }

    public int num1 = getNum1();

    public int getNum1() {
        System.out.println("getNum1() Ordinary function call...");
        return 233;
    }

    {
        System.out.println("Ordinary code block call...");
    }

    public static int num2 = getNum2();

    static {
        System.out.println("Static code block call...");
    }

    public static int getNum2() {
        System.out.println("getNum2() Static function call...");
        return 688;
    }
}

Output:

getNum2() Static function call...
Static code block call...
getNum1() Ordinary function call...
Ordinary code block call...
Number() constructor ...

Note: you can view number Class file = > ordinary code blocks are placed in the constructor and executed first. Continue to read the details.
Number.class

package com.alan.codeblock;

class Number {
    public int num1 = this.getNum1();
    public static int num2 = getNum2();

    public Number() {
        System.out.println("Ordinary code block call...");
        System.out.println("Number() constructor ...");
    }

    public int getNum1() {
        System.out.println("getNum1() Ordinary function call...");
        return 233;
    }

    public static int getNum2() {
        System.out.println("getNum2() Static function call...");
        return 688;
    }

    static {
        System.out.println("Static code block call...");
    }
}

2.3 constructors and common code blocks

The front of the parameterless constructor actually implies super() and calling ordinary code blocks. Statically related code blocks and attribute initialization are executed when the class is loaded, so they take precedence over the constructor and ordinary code blocks.

class A {
	public A() {
    	// Hidden code
        // 1. super();
        // 2. Call normal code block
        System.out.println("A Parameterless constructor for...");
    }
}

Case: codeblockdetail03 java

package com.alan.codeblock;

/**
 * Developer: Zzw
 * Development time: 15:10, June 20, 2021
 * File name: CodeBlockDetail03
 * Development tool: IntelliJ IDEA
 * Project function: constructor and common code block
 */
public class CodeBlockDetail03 {
    public static void main(String[] args) {
        new Student();
    }
}

class Person {

    {
        System.out.println("Person Normal code blocks are executed...");
    }

    public Person() {
        // super();
        // Call normal code block
        System.out.println("Person The parameterless constructor of is executed...");
    }
}


class Student extends Person{

    {
        System.out.println("Student Normal code blocks are executed...");
    }

    public Student() {
        // super();
        // Call normal code block
        System.out.println("Student The parameterless constructor of is executed...");
    }
}

Output:

Person Normal code blocks are executed...
Person The parameterless constructor of is executed...
Student Normal code blocks are executed...
Student The parameterless constructor of is executed...

Explanation: when creating (new) Student class, the calling sequence is:

  1. The hidden super() in the subclass no parameter constructor.
  2. Call the parameterless constructor of the parent class through the super() of the subclass
  3. In the parameterless constructor of the parent class, call the parameterless constructor of the parent class's parent class (Object)
  4. Normal code block of the parent class
  5. The actual code in the parameterless constructor of the parent class
  6. Common code block of subclass
  7. The actual code in the parameterless constructor of the subclass

2.4 calls between static and normal code

Static code blocks can only directly call static members (static attributes and static methods), and ordinary code blocks can call any member.
This is also easy to understand:

  • Static code blocks and static variables are the memory space applied for when the class is loaded. At this time, if the class is not created, there is no instance member variable (ordinary code) of the class, ordinary code blocks and ordinary variables cannot be called, and the this key word cannot be used in static methods.
  • After the class is created, there are ordinary code and static code in memory, so ordinary code can call static members and methods.

III 😁 Comprehensive case (interview)

When creating a subclass object (inheritance relationship), their static code block, static attribute initialization, common code block, common attribute initialization, and the calling sequence of construction methods are as follows:

  1. Static code blocks and static attributes of the parent class (same priority, executed in the order of definition)
  2. Static code blocks and static attributes of subclasses (with the same priority and executed in the order of definition)
  3. Initialization of common code blocks and common attributes of the parent class (same priority, executed in the order of definition)
  4. Construction method of parent class
  5. Initialization of ordinary code blocks and ordinary attributes of subclasses (with the same priority and executed in the order of definition)
  6. Construction method of subclass

Case: codeblockdetail04 java

package com.alan.codeblock;

/**
 * Developer: Zzw
 * Development time: 15:40, June 20, 2021
 * File name: CodeBlockDetail04
 * Development tool: IntelliJ IDEA
 * Project function: a comprehensive case of static code block and ordinary code block
 */
public class CodeBlockDetail04 {
    public static void main(String[] args) {
        new B();
    }
}

class A {
    private int n1 = getVal01();

    static {
        System.out.println("A Static code block execution...");
    }

    {
        System.out.println("A Common code block execution...");
    }

    private static int n2 = getVal02();

    private int getVal01(){
        System.out.println("getVal01 Ordinary function execution...");
        return 1;
    }

    private static int getVal02(){
        System.out.println("getVal02 Static function execution...");
        return 2;
    }

    public A() {
        // super()
        // Common code block
        System.out.println("A Parameterless constructor execution...");
    }

}
class B extends A{

    private int n3 = getVal03();

    static {
        System.out.println("B Static code block execution...");
    }

    {
        System.out.println("B Common code block execution...");
    }

    private static int n4 = getVal04();

    private int getVal03(){
        System.out.println("getVal03 Ordinary function execution...");
        return 1;
    }

    private static int getVal04(){
        System.out.println("getVal04 Static function execution...");
        return 2;
    }

    public B() {
        // super()
        // Common code block
        System.out.println("B Parameterless constructor execution...");
    }
}

Output: for the output of this case, I suggest you analyze it yourself and then look at the following answers

A Static code block execution...
getVal02 Static function execution...
B Static code block execution...
getVal04 Static function execution...
getVal01 Ordinary function execution...
A Common code block execution...
A Parameterless constructor execution...
getVal03 Ordinary function execution...
B Common code block execution...
B Parameterless constructor execution...

3.2 summary

The difficulty of code block mainly lies in the execution order of the code. As long as you understand the execution order, this part is not difficult to understand.

Topics: Java Programming