The Importance Analysis of Interface Initialization Rules and Class Loader Preparation Phase and Initialization Phase

Interface initialization rules:

In the previous examples, it was all done around the class. This time, let's take a look at the initialization of the interface, and create a new example directly:

At this point, write the main method to call the fields in the interface:

According to the previous example of the [ http://www.cnblogs.com/webor2006/p/8835953.html ] class, if the subclass is actively used, other parent classes will also be initialized, and when the static field is called, it The class will also be actively used, recall:

For the interface, there is no static code block to verify whether the class is initialized, so how to fix it? Then run it first:

At this point, the bytecode file will be generated, and then the bytecode file of MyParent5 will be deleted, and then run:

So here is a problem: when an interface is initialized, it is not required that its parent interface has been initialized.

What if the bytecode file of MyChild5 is also deleted? See the result:

It works as well. Isn't it similar to putting the compile-time constant in the constant, uh, the constant? The problem is that there is no declaration as final in the interface:

Then add:

It is grayed out. Obviously, the fields defined for the interface are all constants, so if you delete the bytecode file when the field is declared as a runtime constant, you will definitely get an error. Do you believe it?

This is indeed the case, because such runtime constants will not be placed in the constant pool, so continue to modify the program:

At this time, delete the bytecode file of MyParent5. According to the previous experiment, it should still be output normally. The result:

An exception was thrown! ! So what if the constants in MyParent5 are declared as compile-time constants?

An exception is still thrown, so here is another thing to summarize: only when the parent class interface is actually used (such as when referring to the constants defined in the interface), it will be initialized.

Next continue to transform:

Then delete MyParent5:

Because the data of the constant pool is used in MyChild5, if the interface is changed to a class at this time, the final keyword should be removed before the change:

And because the fields in the interface do not declare final, they are actually constants, so deleting the bytecode MyParent5 must be able to run normally, then change it to class, and everything else remains unchanged:

At this point, delete the bytecode file of MyParent5:

At this point, an exception is thrown, because if a class is declared as final, it is not considered a constant. It shows that the parent class must be initialized when the subclass is initialized. Of course, an exception is thrown. To do these experiments is In order to illustrate the previous summary: when an interface is initialized, it is not required that its parent interface has been initialized. It will only be initialized when the parent interface is actually used (such as when referring to the constants defined in the interface).

Analysis of the significance of the class loader preparation phase and initialization phase:

Let's write a new example as follows:

What is the result? It is easier to understand, as follows:

good! ! Next, modify the code a little bit:

What is the result then? run:

Uh~~ why is this? Let’s make some logs for further observation, and a new continent will be discovered:

Compile and run:

In fact, in the private structure, counter2 is 1, but it is set to 0 because the static declaration of counter2 is placed after it, so why is this happening? Here we have to analyze the loading order of the classes, as follows:

Because we actively call the static method in the class in the main method, as follows:

And according to the seven ways of active use, it belongs to this:

So it will lead to the initialization of the Singleton class, and there will be a preparation phase before initialization, such as:

What did you do in the preparatory stage? [There is little contact with this stage, but it is very important! ] ? It is prepared from top to bottom, so it is also analyzed in the order from top to bottom, as follows:

Well, the preparation phase of the entire class is completed, and then the initialization of the class is prepared. During the initialization phase, the static variables in the class are assigned initial values, which are also executed in the order from top to bottom, so:

OK, here comes the key point:

Then through the above analysis from the preparation to the initialization stage, what is the significance of the preparation stage? Look:

Ok~~ Understand the whole process of the above code, then modify the program again, what will the result be, as follows:

After understanding the previous example, I think the result of this modification can be easily deduced. Here is the result:

【Explanation】 : The above program has no practical value, but it is extremely helpful for understanding the loading process of classes.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324620151&siteId=291194637