编写代码如下:
package com.zuoyan.classloader;
class FinalTest{
public static final int x = 3;
static {
System.out.println("FinalTest static block!");
}
}
public class MyTest01 {
public static void main(String[] args) {
System.out.println(FinalTest.x);
}
}
代码执行结果:
3
然后将FinalTest 类中的 public static final x = 3 中的final 去掉 改成 public satic in x = 3
package com.zuoyan.classloader;
class FinalTest{
public static int x = 3;
static {
System.out.println("FinalTest static block!");
}
}
public class MyTest01 {
public static void main(String[] args) {
System.out.println(FinalTest.x);
}
}
执行结果如下:
FinalTest static block! 3
然后再将 FinalTest 中的成员变量 public static final int x = 3 ,改成 public static final int x = new Random().nextInt(3);
package com.zuoyan.classloader;
import java.util.Random;
class FinalTest{
public static final int x = new Random().nextInt(3);
static {
System.out.println("FinalTest static block!");
}
}
public class MyTest01 {
public static void main(String[] args) {
System.out.println(FinalTest.x);
}
}
代码执行结果如下:
FinalTest static block! 1
Demo01 的执行结果是 3 ,没有输出静态代码块中的内容,就代表静态代码块没有被执行,也就是说类没有被初始化,如果类被初始化了,静态代码块是一定会执行的。
原因是: 本身 x 是 一个编译期的常量,3 在编译之后就会放在MyTest01 的常量池中,所以编译完后,MyTest01 和 FinalTest之间就没有任何关系了,删除FinalTest.class 没有任何关系
Demo02 的执行结果的原因是 : x 不是一个成员变量,需要加载类,所需需要初始化类
Demo03 结果出现的原因是: x 是一个成员变量,但是他的数值实在运行期才能确定的,所以需要加载FinalTest类
代码如下,请判断代码的执行结果
package com.zuoyan.classloader;
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");
}
}
public class MyTest02 {
static {
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
出现这样结果的原因: 首先初始化 Main 方法所在类,然后这类调用了 Child类的成员变量,导致了Child类的初始化,一个类的初始化首先会初始化他的父类,然后初始化他的子类
可用通过运行时 添加JVM参数来查看类的加载
程序执行输出的结果:
package com.zuoyan.classloader;
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("Child 2 static block");
}
}
public class MyTest03 {
static{
System.out.println("MyTest03 static block ");
}
public static void main(String[] args) {
Parent2 parent;
System.out.println("-----------------");
parent = new Parent2();
System.out.println("-----------------");
System.out.println(parent.a);
System.out.println("-----------------");
System.out.println(Child2.b);
}
}
程序执行的结果:
MyTest03 static block ----------------- Parent2 static block ----------------- 3 ----------------- Child 2 static block 4
package com.zuoyan.classloader;
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");
}
}
public class MyTest04 {
public static void main(String[] args) {
System.out.println(Child3.a);
Child3.doSomething();
}
}
程序执行出来的结果:
Parent3 static block
3
do something
注意: a 本身是定义在父类中,我虽然通过子类来访问父类的成员变量,但是在本质上,是对于父类的主动使用,换句话说,就是成员变量定义在哪就是对谁的主动使用 (谁拥有就是对谁的主动使用)。
package com.zuoyan.classloader;
class CL{
static {
System.out.println("Class CL");
}
}
public class MyTest05 {
public static void main(String[] args) throws Exception {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
Class<?> clazz = systemClassLoader.loadClass("com.zuoyan.classloader.MyTest05");
System.out.println(clazz);
System.out.println("----------------------");
clazz = Class.forName("com.zuoyan.classloader.CL");
System.out.println(clazz);
}
}
执行结果:
class com.zuoyan.classloader.MyTest05 ---------------------- Class CL class com.zuoyan.classloader.CL