误区:
安卓开发多少会了解一些虚拟机的概念,但是并不十分熟悉,Android L前后,虚拟机主要差异在于DALVIK(JIT:just in time)和ART(AOT:ahead of time)之间,ART会在应用第一次安装的时候预编译字节码为机器码,提前将多个dex解析为真正的本地应用。
在此前提下安卓开发者可能会认为在dalvik中,dex被加载时static代码块才会被执行,而在art中,代码块会被立即执行。其实这从本质上就是一个错误,因为JAVA静态代码块并不会在类被加载时自动执行。
证错:
class MyClass1 {
static {//静态块
System.out.println("static block ");
}
}
public class Main {
Class[] classArray = {
MyClass1.class//这样引用该类,必然需要将该类加载到虚拟机中
};
public static void main(String[] args){
System.out.println("hello word");
}
}
执行结果:并没有输出" static bolck"
正解:
实际上,一个类的运行分为装载、连接、初始化阶段,各阶段具体介绍详见:
Java的static块执行时机
而static块的执行则发生在“初始化”阶段。初始化阶段,jvm主要完成对静态变量的初始化,静态块执行等工作。
执行static块的几种情况:
- 当创建某个类的新实例时(如通过new或者反射,克隆,反序列化等)
- 当调用某个类的静态方法时
- 当使用某个类或接口的静态字段时
- 当调用Java API中的某些反射方法时,比如类Class中的方法,或者java.lang.reflect中的类的方法时
- 当初始化某个子类时
- 当虚拟机启动某个被标明为启动类的类(即包含main方法的那个类)
注:第一次Class.forName("A",false,this.getClass().getClassLoader())的过程不会执行static代码块。因为false指明了装载类的过程中,不进行初始化。不初始化则不会执行static块。
参考:
Java的static块执行时机
Android中的Dalvik和ART详解及区别分析
JAVA虚拟机与Android虚拟机的区别
网友评论