一、.当运行一个JAVA程序时,JVM的action为:
1.JVM首先会将二进制文件(.class文件)加载到内存中(加载)
2.二进制文件加载到内存后,进行链接动作(链接),链接包括以下三个动作:
(1),校验二进制文件是否符合规范(验证)
(2),为类的静态变量分配内存,同时为他们赋值,该值为其默认初始值(准备)
(3),将类中的符号引用转化为直接引用(解析)
3.完成链接后,JVM会进行初始化,为静态变态赋给他们正确的值。
对以上的相关解释:
链接中准备的赋值操作,是给对应的静态变量赋予他们默认的值,例如int型赋值为0,而初始化中的赋给正确的值指由程序赋予的值,示例代码如下:
public static int a = 1;
public static int b;
以上两个静态变量,赋值的过程为,首先是在链接过程中,通过准备操作,给他们赋值,该值为int型默认的0,
然后在初始化的过程中,由于a再被赋值为1,b由于没有被程序赋值,所以值还是系统默认的0。
衍生扩展:
public class Test{
private static Test t = new Test();
private static int a = 0;
private static int b;
private Test(){
a++;
b++;
}
public static Test getNewInstanc() {
return t;
}
public static void main(String[] args){
Test tt = Test.getNewInstanc();
System.out.println("a is: "+ a);
System.out.println("b is: "+ b);
}
}
代码执行结果:
a is 0
b is 1
解析:当运行程序时,JVM在链接阶段首先为t, a .b 赋初,分别是null,0,0。
在初始化阶段时,首先生成Test对象,调用构造方法,此时a=1, b=1,
代码继续往下执行, a再次被程序赋值为0,由于b没有被赋值,因此还是1,
所以最后打印结果为a is 0 ,b is 1.
符号引用用代码表示为
import com.xx.xx.Car;
...
//Car在某个地方被初始化
Car car = new Car();
public void dosth(){
car.run() // 该段代码即是符号引用,JVM在链接阶段时,会把这个引用其他类的方法转化为直接引用,可以理解成Car.run();
}