Initialization sequence of Static variables and instance variables

Source: Internet
Author: User

Problem Reproduction

Let's take a look at the following program:


1 public class StaticInitSequence {
2 // ------------------- Static fields -------------------
3 private static int staticIntVar = 10;
4 private static int staticComputeIntVar = (int) (Math. random () * 10 );
5 private static String staticStrVar = "Static field init (before )";
6 private static Object staticRefVar = new Object ();
7
8 static {
9 staticIntVar = 20;
10 staticStrVar = "Static block init (before )";
11 staticAfterIntVar = 40;
12 staticAfterStrVar = "Static block init (after )";
13}
14
15 private static int staticAfterIntVar = 30;
16 private static String staticAfterStrVar = "Static field init (after )";
17
18 // --------------------- Instance fields ----------------
19 private int fieldIntVar = 100;
20 private int fieldComputeIntVar = (int) (Math. random () * 100 );
21 private String fieldStrVar = "Instance field init (before )";
22
23 public StaticInitSequence (){
24 fieldIntVar = 200;
25 fieldStrVar = "Constructor field init (before )";
26
27 fieldAfterIntVar = 400;
28 fieldAfterStrVar = "Constructor field init (after )";
29}
30
31. private int fieldAfterIntVar = 300;
32 private String fieldAfterStrVar = "Instance field init (after )";
33
34 public void print (){
35 System. out. println ("---------------- Static Fields ------------");
36 System. out. println ("staticIntVar:" + staticIntVar );
37 System. out. println ("staticComputeIntVar:" + staticComputeIntVar );
38 System. out. println ("staticStrVar:" + staticStrVar );
39 System. out. println ("staticRefVar:" + staticRefVar );
40 System. out. println ("staticAfterIntVar:" + staticAfterIntVar );
41 System. out. println ("staticAfterStrVar:" + staticAfterStrVar );
42
43 System. out. println ("----------------- Instance Fields ---------");
44 System. out. println ("fieldIntVar:" + fieldIntVar );
45 System. out. println ("fieldComputeIntVar:" + fieldComputeIntVar );
46 System. out. println ("fieldStrVar:" + fieldStrVar );
47 System. out. println ("fieldAfterIntVar:" + fieldAfterIntVar );
48 System. out. println ("fieldAfterStrVar:" + fieldAfterStrVar );
49}
50}
What will happen if we call the print () method (new StaticInitSequence (). print () of the preceding class?

In my opinion, initializing a field directly is a programming method supported by the compiler. This programming method can improve the readability of the Code, because you can directly know the initial value of a field, instead of looking for it in the constructor or static statement block. In Java, In the compiled binary file, all the field initialization statements are placed in the initialization function (Class (static) initialization function (<clinit>) or the instance initialization (constructor/<init>) function ). Therefore, in my logic thinking, in the source code, the initialization function should be able to change the value in the field initialization, so that an initial value can be provided in the field initialization, in the initialization function, change it as needed. However, I am surprised that only the instance initialization mechanism in Java is implemented in this way, this mechanism is not implemented in static field initialization (this mechanism is implemented in C # Regardless of instance initialization and static initialization ), the initialization sequence of static fields is fully initialized according to the defined sequence in the source code. From the coupling perspective, this is a typical type of sequential coupling. I don't know why Java is implemented like this. Is there any other considerations? Or a mistake made by the Java designer or the Java compiler designer? In any case, the running results of the above programs compiled with sun's javac are as follows:


---------------- Static Fields ------------
StaticIntVar: 20
StaticComputeIntVar: 7
StaticStrVar: Static block init (before)
StaticRefVar: java. lang. Object @ 14318bb
StaticAfterIntVar: 30
StaticAfterStrVar: Static field init (after)
--------------- Instance Fields ---------
FieldIntVar: 200
FieldComputeIntVar: 8
FieldStrVar: Constructor field init (before)
FieldAfterIntVar: 400
FieldAfterStrVar: Constructor field init (after)
 

Explanation:

From the binary code generated by the above program, the above results can be well explained:

 

<Clinit>:
// StaticIntVar = 10
0 bipush 10
2 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticIntVar: int [22]
// StaticComputeIntVar = (int) (Math. random () * 10)
5 invokestatic java. lang. Math. random (): double [24]
8 ldc2_w <Double 10.0> [30]
11 dmul
12 d2i
13 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticComputeIntVar: int [32]
// StaticStrVar = "Static field init (before )"
16 ldc <String "Static field init (before)"> [34]
18 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticStrVar: java. lang. String [36]
// StaticRefVar = new Object ();
21 new java. lang. Object [3]
24 dup
25 invokespecial java. lang. Object () [38]
28 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticRefVar: java. lang. Object [41]
// StaticIntVar = 20
31 bipush 20
33 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticIntVar: int [22]
// StaticStrVar = "Static block init (before )"
36 ldc <String "Static block init (before)"> [43]
38 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticStrVar: java. lang. String [36]
// StaticAfterIntVar = 40
41 bipush 40
43 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticAfterIntVar: int [45]
// StaticAfterStr = "Statci block init (after )"
46 ldc <String "Static block init (after)"> [47]
48 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticAfterStrVar: java. lang. String [49]
// StaticAfterIntVar = 30
51 bipush 30
53 putstatic org. levin. insidejvm. miscs. staticinit. StaticInitSequence. staticAfterIntVar: int [45]
// StaticAfterStrVar = "Static field init (after )"
56 ldc <String "Static field init (after)"> [51]
58 putstatic org. levin. insidejvm.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.