一道JVM面试题,答错率超90%

package com.yanqun.pojo;

class MyClass{

   static int num1 = 100 ;

   static MyClass myClass = new MyClass();
   
   public MyClass(){
       num1 = 200 ;
       num2 = 200 ;
   }
   
   static int num2 = 100 ;
   
   public static MyClass getMyClass(){
       return myClass ;
   }

   @Override
   public String toString() {
       return this.num1 + "	" + this.num2 ;
   }
}


public class MyClassLoader {

    public static void main(String[] args) {
    
        MyClass myc =  MyClass.getMyClass() ;
        
        System.out.println(myc);
        
    }
}

运行结果:200 100

 

解析:

JVM使用“类”的生命周期是:

类的加载->连接->初始化->使用->卸载

 

各阶段主要完成的工作如下:

1.类的加载:

(1)寻找并加载类的二进制数据(class文件)

(2)将硬盘上的class文件 加载到jvm内存中

 

2.连接

该阶段又包含了验证、准备和解析3个过程,如下。

(1)验证

校验.class文件的正确性

(2)准备

 

给static静态变量分配内存,并初始化static的默认值。

因此,本题在此阶段各变量的值如下:

static int num1 = 0 ;

static MyClass myClass = null ;

static int num2 = 0 ;

(3)解析:把类中符号引用,转为直接引用

举个例子,在加载阶段,JVM还不知道类的具体内存地址,只能使用“com.yanqun.pojo.MyClass ”来替代MyClass类,“com.yanqun.pojo.MyClass ”就称为符号引用;但在解析阶段,JVM就可以将 “com.yanqun.pojo.MyClass ”映射成实际的内存地址,因此就可以用 内存地址来代替MyClass,这种使用 内存地址来使用 类的方法 称为直接引用。

 

3.初始化:给static变量 赋予实际的值

因此,本题在此阶段各变量的值如下:

static int num1 = 100 ;

static MyClass myClass = new MyClass();此句调用了构造方法,构造方法会进行如下赋值:

public MyClass(){

num1 = 200 ;

num2 = 200 ;

}

static int num2 = 100 ;

根据程序 自上而下执行的特点,num1最终的值是200,num2最终的值是100。

 

4.使用:对象的初始化、对象的垃圾回收、对象的销毁

 

5.卸载

转载于:https://zhuanlan.zhihu.com/p/94290578

原文地址:https://www.cnblogs.com/it-deepinmind/p/12419013.html