public class MyTest8 {
public static void main(String[] args){
System.out.println(FinalTest.x);
}
}
class FinalTest {
public static final int x = 3;
static {
System.out.println("FinalTest static block");
}
}
不会输出静态代码块的文字,说明FinalTest没有被初始化,常量x放入了MyTest8的常量池中
public static int x = 3; //没有进入常量池 public static final int x = new Random().nextInt(3); //运行期才会确定
上面两种情况会输出文字FinalTest static block
class Parent {
static int a = 3;
static {
// 2
System.out.println("Parent static block");
}
}
class Child extends Parent {
static int b = 4;
static {
// 3
System.out.println("Child static block");
}
}
public class MyTest9 {
static {
// 1
System.out.println("MyTest9 static block");
}
public static void main(String[] args){
System.out.println(Child.b);
}
}
依次输出:
MyTest9 static block
Parent static block
Child static block
4
class Parent2 {
static int a = 3;
static {
System.out.println("Parent2 static block");
}
}
class Child2 extends Parent2 {
static int b = 4;
static {
System.out.println("Child2 static block");
}
}
public class MyTest10 {
static {
System.out.println("MyTest10 static block");
}
public static void main(String[] args){
Parent2 parent2; // 不会导致任何输出
System.out.println("***************");
parent2 = new Parent2();
System.out.println("***************");
System.out.println(parent2.a); // 只初始化一次
System.out.println("***************");
System.out.println(Child2.b);
}
}
输出:
MyTest10 static block
***************
Parent2 static block
***************
3
***************
Child2 static block
4
class Parent3 {
static int a = 3;
static {
System.out.println("Parent3 static block");
}
static void doSomething(){
System.out.println("Parent3 doSomething");
}
}
class Child3 extends Parent3 {
static {
System.out.println("Child2 static block");
}
}
public class MyTest11 {
public static void main(String[] args){
System.out.println(Child3.a); // 因为a是父类的,虽然通过子类访问,但是表示的是对父类的主动使用
System.out.println("*************");
Child3.doSomething();
}
}
输出
Parent3 static block
3
*************
Parent3 doSomething
子类调用父类的静态方法也不会导致子类的初始化,属于对父类的主动使用
/**
* 调用ClassLoader类的loadClass方法加载一个类,并不是对类的主动使用,不会导致类初始化
*/
class CL {
static {
System.out.println("Class CL");
}
}
public class MyTest12 {
public static void main(String[] args) throws Exception{
ClassLoader loader = ClassLoader.getSystemClassLoader();
// 不会导致类的初始化
Class<?> clazz = loader.loadClass("com.yshuoo.jvm.classloader.CL");
System.out.println(clazz);
System.out.println("******************");
// 反射属于主动使用,会导致类的初始化
clazz = Class.forName("com.yshuoo.jvm.classloader.CL");
System.out.println(clazz);
}
}
输出:
class com.yshuoo.jvm.classloader.CL
******************
Class CL
class com.yshuoo.jvm.classloader.CL