

1、Java
虚拟机如何对变量赋值?
对于非 static 类型的变量(即实例变量)的赋值是在实例构造器 <init> 方法中进行的;
对于类变量,则由两种方法可以选择:在类构造器 <clinit> 方法中或使用ConstantValue 属性。目前 Sun Javac 编译器的选择是:如果同时使用 final 和 static 来修饰一个变量(按照习惯,这里用"常量"更贴切),并且这个变量的数据类型是基本类型或 String 类型的话,就生成 ConstantValue 属性来初始化,如果这个变量没有被 final 修饰,或者并非基本类型或字符串,则将会选择在 <clinit> 方法中进行初始化。
2、在将一个浮点值窄化转换为整数类型 T (T 限于 int 或 long 类型之一)的时候,将遵循什么转换规则?
如果浮点值是 NaN,那转换结果就是 int 或 long 类型的 0;
如果浮点值不是无穷大的话,浮点值使用 IEEE 754 的向零舍入模式取整,获得整数值 v,如果 v 在目标类型 T(int 或 long)的表示范围之内,那转换结果就是 v;
否则,将根据 v 的符号,转换为 T 所能表示的最大或者最小正数。
3、Java 虚拟机的实现主要有哪两种方式?
1)将输入的Java 虚拟机代码在加载或执行时翻译成另外一种虚拟机的指令集;
2)将输入的Java 虚拟机代码在加载或执行时翻译成宿主机 CPU 的本地指令集 (即 JIT 代码生成技术)
4、Java 虚拟机规范严格规定了哪5种场景下,必须立即对类进行 "初始化"(而加载、验证、准备自然需要在此之前开始)?
1)遇到new、getstatic、putstatic、invokestatic 这 4 条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这 4 条指令的最常见的 Java 代码场景是:使用 new 关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
2)对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3)当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
4)当虚拟机启动时,用户需要指定一个要执行的主类(包含main方法的那个类),虚拟机会先初始化这个主类。
5)当使用JDK1.7 的动态语言支持时,如果一个MethodHandler实例最后的解析结果对应方法句柄的类没有进行过初始化,则需要先触发其初始化。
5、在加载阶段,虚拟机需要完成哪三件事情?
1)通过一个类的全限定名来获取定义此类的二进制字节流;
2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
3)在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口。




