துவக்க தொகுதிகள் (நிலையான மற்றும் நிலையான அல்லாத), கட்டமைப்பாளர்கள் மற்றும் நிலையான மற்றும் நிலையான புலங்களின் துவக்கத்தில் குறியீடு செயல்படுத்தப்படும் வரிசையைப் பார்ப்போம். குறியீட்டை இயக்குவதன் மூலம் நடைமுறையில் என்ன நடக்கிறது என்பதை நாங்கள் ஆராய்வோம்.
தொடங்குவதற்கு, சாத்தியமான ஒவ்வொரு உறுப்புகளின் முழு தொகுப்பைக் கொண்ட ஒரு வகுப்பு எங்களிடம் உள்ளது:
public class MyClass {
static {
System.out.println("Static Block #1.");
}
public static String staticField = setStaticField();
public MyClass() {
System.out.println("Constructor.");
}
static {
System.out.println("Static Block #2.");
}
{
System.out.println("Initialization Block #1.");
}
public String nonStaticField = setNonStaticField();
{
System.out.println("Initialization Block #2.");
}
private String setNonStaticField() {
System.out.println("Non-static field.");
return "nonStaticField";
}
private static String setStaticField() {
System.out.println("Static field.");
return "staticField";
}
public static void print() {
System.out.println("print() method.");
}
}
இப்போது, இந்த வகுப்போடு, ஒரு முக்கிய முறையுடன் மற்றொன்றை உருவாக்கி , அதை இயக்குவோம்:
public class Solution {
public static void main(String args[]) {
System.out.println("hello");
}
}
வெளியீடு எதையும் உள்ளடக்கியது MyClass
class. There were no calls to MyClass
methods, so the class was not even loaded. Let's now try to call the static print()
method of the MyClass
class. Twice.
public class Solution {
public static void main(String args[]) {
MyClass.print();
MyClass.print();
}
}
Output:
Static field.
Static Block #2.
print() method.
print() method.
Only the static initialization blocks were executed and the static field was initialized. And this happened only once. That's because the class was already loaded when we made the second call to the print() method. Remember: static fields are initialized and initialization blocks are executed once upon the first interaction with the class.
Note that static blocks are executed and fields are initialized in the order they are declared.
Next, instead of calling a static method, let's try creating two objects of our class:
public class Solution {
public static void main(String args[]) {
new MyClass();
System.out.println();
new MyClass();
}
}
Output:
Static field.
Static Block #2.
Initialization Block #1.
Non-static field.
Initialization Block #2.
Constructor.
Initialization Block #1.
Non-static field.
Initialization Block #2.
Constructor.
First, static blocks are executed and static fields are initialized once. After that, each time an object is created, the non-static blocks, fields, and a constructor are processed. The fields and initialization blocks are processed in the order of their declaration, but the constructor is processed at the end — no matter where it is declared.
Let's complicate the example — we'll take two classes, where one of them inherits the other:
public class ParentClass {
static {
System.out.println("Static Block #1 of the parent class.");
}
public static String parentStatic = setParentStatic();
static {
System.out.println("Static Block #2 of the parent class.");
}
{
System.out.println("Initialization Block #1 of the parent class.");
}
public String parentNonStatic = setParentNonStatic();
{
System.out.println("Initialization Block #2 of the parent class.");
}
public ParentClass() {
System.out.println("Constructor of the parent class.");
}
private String setParentNonStatic() {
System.out.println("Non-static field of the parent class.");
return "parentNonStatic";
}
private static String setParentStatic() {
System.out.println("Static field of the parent class.");
return "parentStatic";
}
public String setChildNonStatic1() {
System.out.println("Non-static field of the child class #1.");
return "childNonStatic2" + parentNonStatic;
}
}
public class ChildClass extends ParentClass {
static {
System.out.println("Static Block #1 of the child class.");
}
public static String childStatic = setChildStatic();
static {
System.out.println("Static Block #2 of the child class.");
}
public String childNonStatic1 = setChildNonStatic1();
{
System.out.println("Initialization Block #1 of the child class.");
}
public String childNonStatic2 = setChildNonStatic2();
{
System.out.println("Initialization Block #2 of the child class.");
}
public ChildClass() {
System.out.println("Constructor of the child class.");
}
private String setChildNonStatic2() {
System.out.println("Non-static field of the child class #2.");
return "childNonStatic";
}
private static String setChildStatic() {
System.out.println("Static field of the child class.");
return "childStatic";
}
}
Let's create two objects of the child class:
public class Solution {
public static void main(String[] args) {
new ChildClass();
System.out.println();
new ChildClass();
}
}
Output:
Static field of the parent class.
Static Block #2 of the parent class.
Static Block #1 of the child class.
Static field of the child class.
Static Block #2 of the child class.
Initialization Block #1 of the parent class.
Non-static field of the parent class.
Initialization Block #2 of the parent class.
Constructor of the parent class.
Non-static field of the child class #1.
Initialization Block #1 of the child class.
Non-static field of the child class #2.
Initialization Block #2 of the child class.
Constructor of the child class.
Initialization Block #1 of the parent class.
Non-static field of the parent class.
Initialization Block #2 of the parent class.
Constructor of the parent class.
Non-static field of the child class #1.
Initialization Block #1 of the child class.
Non-static field of the child class #2.
Initialization Block #2 of the child class.
Constructor of the child class.
From the new output, we see that the static blocks and variables of the parent class are processed before the static blocks and variables of the child class. It's the same with non-static blocks and variables and constructors: first the parent class, then the child class. To understand why this is necessary, take a look at the example of the childNonStatic1 field of the child class. A method of the parent class is used to initialize it, and that method in turn uses a variable of the parent class. That means that when the childNonStatic1 field is initialized, the parent class and its methods must already be loaded, and the variables of the parent class must be initialized.
In practice, you may not encounter classes that include all of these elements all at once, but it will be useful for you to remember what gets initialized before what. Oh, and this is also often asked about in job interviews.
GO TO FULL VERSION