- Preface
- Definition
- Features
- Syntax
- Application Circumstances
- Points For Attention
- Code Demonstration
Preface :
Well,we have already learned the "static" keyword and talked about some questions about it before, such as, what is "static" keyword and how to use it? But more than that, since up's recently bolg of "static" push our undertanding of this keyword, we're ready to learn something new and interesting, which is the "Code block".
Definition :
Also known as "Initializer block", "Code block" isa member belongs to a class. I mean it's a part of class. As we know, "method" is formed by encapsulating some logic statements in a method body, and then surrounding them with braces. Similarly, the "Code block" is something just like a kind of "method" with only having method body.
As shown in the following figure :
Features :
Compared to "method", the "Code block" has no return type, no method name, and no list of formal parameters, it only has the "body". And, instead of invoking it by a created object or using it like class method explicitly, "Code block" is invoked implicitly by loading its class or creating an object of its class.
Code Demonstrate :
up will creat a class named "Demo1", and than creat another class named "TestDemo1" as a test class. As shown in the following code :
packageknowledge.polymorphism.code_block; publicclassDemo1 { { System.out.println("This is code block, hahah"); System.out.println("It is written in class directly, not in methods"); System.out.println("It's a member of a class."); } } classTestDemo1 { publicstaticvoidmain(String[] args) { /*The plain code block is invoked implicitly each time we create a new object of its class. */Demo1demo1=newDemo1(); System.out.println("-----------------------------------"); Demo1demo1_2=newDemo1(); } }
Running results :
Syntax :
[modifier] {
//body (code)
};
PS :
- As to modifier, you can neglect it. But you want to add a modifier for a code block, you can only add the "static" keyword.
- If a code block is modified by "static" we will call it "static code block" while a non-modified code block is called "plain code block".
- As to code block's body, since code block can be regarded as a "three none" method, you can write any logic statements you want which can be written into normal method.
- As to the last ';' of the code block, you can neglect it, too. (suggested to write on)
Application Circumstances :
Most likely, if there are some duplicate statements in different constructor you can extract them to a code block, which can improve the reusability of the code.
Code Demonstrate :
We still use Demo1 and TestDemo1 class to demonstrate the application circumstances。We define two parametric constructors and one parameterless constructor. Suppose that every constructor contains some same fields of a poem. For example, "物华天宝,龙光射牛斗之墟;人杰地灵,徐孺下陈蕃之榻。"
If we just neglect these duplicate codes and create new object normally. The following effects will appear.
As shown in the following code :
packageknowledge.polymorphism.code_block; publicclassDemo1 { publicDemo1() { System.out.println("物华天宝,龙光射牛斗之墟;"); System.out.println("人杰地灵,徐孺下陈蕃之榻。"); System.out.println("This is parameterless constructor."); } publicDemo1(Stringname) { System.out.println("物华天宝,龙光射牛斗之墟;"); System.out.println("人杰地灵,徐孺下陈蕃之榻。"); System.out.println("This is the first parametric constructor."); System.out.println("And the passed parameter is :"+name); } publicDemo1(intage) { System.out.println("物华天宝,龙光射牛斗之墟;"); System.out.println("人杰地灵,徐孺下陈蕃之榻。"); System.out.println("This is the second parameterless constructor."); System.out.println("And the passed parameter is :"+age); } } classTestDemo1 { publicstaticvoidmain(String[] args) { //create an object by using parameterless constructor.Demo1demo1=newDemo1(); System.out.println("==================================================="); //create an object by using the first parametric constructor.Demo1demo1_2=newDemo1("Cyan_RA9"); System.out.println("==================================================="); //create an object by using the second parametric constructor.Demo1demo1_3=newDemo1(20); } }
Running results :
🆗,if you want to write like this, it's okey actually. But, if there are fucking many duplicate codes in different constructors, your codes will be seen very very chubby. So, that's why we're more willing to use code block. Here is our improved codes following : (picture)
As you have seen, we extract these duplicate codes to a code block, and the running results will not change, as shown in the following GIF picture :
Points For Attention(significant) :
Point_ONE :
The static code block, used to initialize the entire class, will be executed when its class was loaded up. Since a class will only be loaded up once, so its static block will be executed only once.
As to non-static code block, it's a little different from the static code block. The non-static block will be executed each time we instantiate its class or you can say each time we create a new object belongs to this class.
Point_TWO :
At what time did the class is been loaded up by the "Class_Loader"?
Well, actually, there are four major types :
①When we create a new object of a class——that is, when we instantiate a class.
②When we wanna access a class's static members.
③When a subclass is going to be loaded up, jvm would first load up its superclass.
④When we create a object in a way of using reflecting.
PS :
Remember, one class could just be loaded up for only one time.
Point_THREE :
What's the order of executing different members of a class when we create a new object ?
Well, the actual order can be totally divided into three stages :
①The first one is to execute the static code blocks and the initialization of the static fields of the class. Definitely they are in a same priority, so if you define many static code blocks and static fields at a same time the order of execution is determined by the order of definition.
②The second one is to execute the non-static code blocks and the initialization of the non-static fields of the class. Similarly, they are in a same priority, so if you define many non-static code blocks and non-static fields at a same time the order of execution is determined by the order of definition.
③And the last one is to execute the constructor of the class.
Point_FOUR :
When we are talking about the mechanism of the inheriting, we have said that there is one hided "super" sentence in the head of the constructor. But, today, this theory need to be complemented something new, which is——after the "super" sentence, there is a hided sentence more which is used to invoke the non-static code blocks of the class.
So, this complement can be a explanation of the execution order which we mentioned above.
Point_FIVE :
This point maybe is the most complicated one to comprehended, so, be more attentive.
What's the order of executing different members between a subclass and a superclass when we create a new object of subclass ?
Well, the actual execution order can be totally divided into six stages :
①The first one is to execute the static code blocks and the initialization of the static fields of the superclass. Again, they're in a same priority, so if you define many static code blocks and static fields at a same time the order of execution is determined by the order of definition.
②The second one is to execute the static code blocks and the initialization of the static fields of the subclass. (Similarly, for the same reason with above.)
③The third one is to execute the non-static code blocks and the initialization of the non-static fields of the superclass.(Similarly, for the same reason with above.)
④The fourth one is to execute the constructor of the superclass.
⑤The fifth one is to execute the non-static code blocks and the initialization of the non-static fields of the subclass.(Similarly, for the same reason with above.)
⑥And the last one is to execute the constructor of the subclass.
Point_SIX :
A static code block can only invoke static members of the class while a non-static code block can use any type members of the class.
Code Demonstration (illustrate points above) :
illustration_one :
Suppose "Pear" class is the demonstration class while "Test_one" class is the test class. up will define a static code block and a non-static code block. By instantiating the "Pear" class, we can observe the situation of execution of the code blocks.
As shown in the following codes :
packageknowledge.polymorphism.code_block.english.detail_one; publicclassPear { { System.out.println("This is Pear's non-static code block."); System.out.println("And this code block will be executed each time we create a Pear object."); System.out.println("-------------------"); } static { System.out.println("This is Pear's static code block."); System.out.println("And this code block will only be executed once when the Pear class is loaded."); System.out.println("========================================"); } } classTest_one { publicstaticvoidmain(String[] args) { Pearpear_0=newPear(); Pearpear_1=newPear(); Pearpear_2=newPear(); } }
Running Results :
illustration_two :
Suppose "Pig" class is the demonstration class while "Test_two" class is the test class.
Actually I has illustrated the whole second point in my blog of reflecting😂. In this case, I am willing to illustrate that the class will be loaded when we use its static members, such as, class variables or class methods.
As shown in the following codes :
packageknowledge.polymorphism.code_block.english.detail_2; publicclassPig { staticStringname="pig"; static { System.out.println("Pig's static code block."); System.out.println("It wil be executed if Pig class is loaded."); System.out.println("========================"); } } classTest_two { publicstaticvoidmain(String[] args) { System.out.println("name = "+Pig.name); } }
Running Results :
illustration_three :
Suppose "Student" class is the demonstration class while "Test_three" class is the test class. We will define a static field "name", a non-static field "age", including their initialization method. What's more, we will also define a static code block and a non-static code block. Observe the console carefully when the Test_three class runs.
As shown in the following codes :
packageknowledge.polymorphism.code_block.english.detail_3; publicclassStudent { privatestaticStringname=getName(); privateintage=getAge(); publicstaticStringgetName() { System.out.println("This static method is used to initialize the static fields of Student."); return"student"; } publicintgetAge() { System.out.println("This non-static method is used to initialize the non-fields."); return0; } { System.out.println("Student's non-static code block."); System.out.println("---------------------------------"); } static { System.out.println("Student's static code block."); System.out.println("---------------------------------"); } publicStudent() { System.out.println("The Student class 's parameterless constructor"); } } classTest_three { publicstaticvoidmain(String[] args) { Studentstudent=newStudent(); } }
Running Results :
illustration_four :
Suppose "Son" class is the demonstration subclass which inherits the demonstration superclass "Father" class while "Test_three" class is the test class.
As shown in the following codes :
packageknowledge.polymorphism.code_block.english.detail_4; publicclassFather { //Superclass : FatherpublicFather() { //super();/*There is also a super sentence in the head of superclass, but the Father'ssuperclass is Object, you know, nothing.*///Actually here also hide one sentence to invoke its non-static code block.//And that's why the Father's non-static code block will finally be executed.System.out.println("Father's parameterless constructor."); System.out.println("----------------------------------"); } { System.out.println("Father's non-static code block."); } } classSonextendsFather { //Subclass : SonpublicSon() { //super(); //Here Hide this super sentence (by default).//Actually also hide one sentence to invoke its non-static code block.//But, To highlight the detail_4, we didn't define any code blocks in subclass.System.out.println("Son's parameterless constructor"); } } classTest_four { publicstaticvoidmain(String[] args) { Sonson=newSon(); } }
Running Results :
illustration_five :
Suppose that "Apple" class is the demonstration subclass which inherits the demonstration superclass "Fruit" class while the "Test_five" class is the test class.
As shown in the following codes :
packageknowledge.polymorphism.code_block.english.detail_5; publicclassFruit { privateStringname=getName(); privatestaticStringsmell=getSmell(); publicStringgetName() { System.out.println("5.This Fruit's non-static method is used to initialize the non-static field"); return"fruit"; } publicstaticStringgetSmell() { System.out.println("1.This Fruit's static method is used to initialize the static field."); return"fruit's smell"; } { System.out.println("6.Fruit's non-static code block"); System.out.println("============================"); } static { System.out.println("2.Fruit's static code block"); System.out.println("============================"); } publicFruit() { System.out.println("7.Fruit's parameterless constructor."); System.out.println("============================"); } } classAppleextendsFruit { privateStringapple_name=getAppleName(); privatestaticStringcolor=getColor(); publicStringgetAppleName() { System.out.println("8.Apple's non-static method, used to initialize the \"apple_name\"."); return"apple"; } publicstaticStringgetColor() { System.out.println("3.Apple's static method, used to initialize the \"color\"."); return"apple's color"; } { System.out.println("9.Apple's non-static code block."); System.out.println("============================"); } static { System.out.println("4.Apple's static code block."); System.out.println("============================"); } publicApple() { System.out.println("10.Apple' parameterless constructor."); } } classTest_five { publicstaticvoidmain(String[] args) { Appleapple=newApple(); } }
Running_Results :
illustration_six :
Suppose the "Worker" class is the demonstration class while the "Test_six" class is the test class. We try invoking the non-static members of the class in the static code block. And let's take a look at what will happen.
As shown in the following codes :
packageknowledge.polymorphism.code_block.english.detail_6; publicclassWorker { privatestaticStringname="Cyan"; privateintage=20; { System.out.println("This is the non-static code block of the Worker"); System.out.println("name = "+name); System.out.println("age = "+age); } static { System.out.println("This is the static code block of the Worker"); System.out.println("name = "+name); //System.out.println("age = " + age);//The static code block can't use the non-static variable "age".System.out.println("======================================================"); } } classTest_six { publicstaticvoidmain(String[] args) { Workerworker=newWorker(); } }
Running Results :
If we wanna invoke non-static members of the class in the static code block, IDEA will give us a Error report, like following pirture :
So, that's all we have above. I appreciate whoever read and leave commends on articles.