java虚拟机如何跑一个程序 从整体上看一个程序 详细实验
如题,本文就是通过实验来测试。
java虚拟机什么时候初始化一个类?
public class ClassLoaderTest{
static {
System.out.println(" 执行静态 块 static block ");
}
public static int age=getAge();
public String str=getString();
public ClassLoaderTest(){
System.out.println("执行 构造方法 ClassLoaderTest()");
}
public static int getAge(){
System.out.println("执行 getAge() ,给类变量age赋值");
return 1;
}
public static String getString(){
System.out.println(" 执行 getString(),给实例变量str赋值");
return "String ";
}
{
System.out.println(" 执行实例 块 block ");
}
public static void main(String[] args){
ClassLoaderTest c1;
System.out.println("before new1");
c1=new ClassLoaderTest();
System.out.println("after new1");
ClassLoaderTest c2;
System.out.println("before new2");
c2=new ClassLoaderTest();
System.out.println("after new2");
}
}
执行结果:
我们可以看到
- 当执行main时,java虚拟机会初始化类,包括静态块并且为静态变量赋值。
- 实例化时,会先为实例变量赋值,执行实例块,最后调用构造函数
- 一个类只会初始化一次
继续验证初始化类的时候:
public class Test{
public static void main(String[] args){
ClassLoaderTest c1;
System.out.println("before new1");
c1=new ClassLoaderTest();
System.out.println("after new1");
ClassLoaderTest c2;
System.out.println("before new2");
c2=new ClassLoaderTest();
System.out.println("after new2");
}
}
运行结果:
明显发现运行结果不同,在一次证明了只有main方法的主类会被先初始化
并且我们深入研究这个结果:发现声明语句并没有初始化类的效果。
继续深入研究,初始化的这个类什么时候会被回收?
public class Test{
public void test(){
ClassLoaderTest c1;
System.out.println("before new1");
c1=new ClassLoaderTest();
System.out.println("after new1");
}
public void test2(){
ClassLoaderTest c2;
System.out.println("before new2");
c2=new ClassLoaderTest();
System.out.println("after new2");
}
public static void main(String[] args){
Test t1=new Test();
t1.test();
t1.test2();
}
}
运行结果:
可以发现这里并没有被回收,我想应该要等全部结束后才能回收。
最后,我想说点题外话:真正的大师应该永保一颗谦逊之心,希望用此来提醒自己。