編譯常量、ClassLoader類、系統類加載器深度探析
類的初始化
- 類的初始化步驟
- 類的初始化時機
例子:
/**
* @name: FinalTest
* @author: terwer
* @date: 2022-07-05 21:51
**/
public class Test2 {
public static void main(String[] args) {
System.out.println(FinalTest.x);
}
}
class FinalTest {
public static final int x = 6 / 3;
static {
System.out.println("FinalTest static block");
}
}
運行結果
/**
* @name: Test3
* @author: terwer
* @date: 2022-07-05 22:24
**/
public class Test3 {
public static void main(String[] args) {
System.out.println(FinalTest2.x);
}
}
class FinalTest2{
public static final int x = new Random().nextInt(100);
static {
System.out.println("FinalTest2 static block");
}
}
前面一個 x 是常量,編譯時候可以確定,因此,不會初始化類。
後面一個 x 在編譯階段無法確定,運行階段才能確定因此,會初始化類。
例子
/**
* @name: Test4
* @author: terwer
* @date: 2022-07-05 22:52
**/
public class Test4 {
static {
System.out.println("Test4 static block");
}
public static void main(String[] args) {
System.out.println(Child.b);
}
}
class Parent {
static int a = 3;
static {
System.out.println("Parent static block");
}
}
class Child extends Parent {
static int b = 4;
static {
System.out.println("Child static block");
}
}
運行結果
例子
/**
* @name: Test5
* @author: terwer
* @date: 2022-07-05 23:02
**/
public class Test5 {
static {
System.out.println("Test5 static block");
}
public static void main(String[] args) {
Parent2 parent;
System.out.println("-----------------");
parent = new Parent2();
System.out.println(Parent2.a);
System.out.println(Child2.b);
}
}
運行結果
程序中對子類的“主動使用”會導致父類被初始化,但是,對父類的主動使用並不會導致子類初始化(不可能說生成一個 Object 類的對象就導致系統中所有的子類都被初始化)。
例子
/**
* @name: Test6
* @author: terwer
* @date: 2022-07-05 23:27
**/
public class Test6 {
public static void main(String[] args) {
System.out.println(Child3.a);
Child3.dosomething();
}
}
class Parent3 {
static int a = 3;
static {
System.out.println("Parent3 static block");
}
static void dosomething() {
System.out.println("do something");
}
}
class Child3 extends Parent3 {
static {
System.out.println("Child3 static block");
}
}
運行結果
例子
/**
* @name: Test7
* @author: terwer
* @date: 2022-07-05 23:45
**/
public class Test7 {
public static void main(String[] args) throws Exception {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class<?> clazz = classLoader.loadClass("com.terwergreen.classloader.C");
System.out.println("-------------------");
Class.forName("com.terwergreen.classloader.C");
}
}
class C {
static {
System.out.println("Class C");
}
}
運行效果