b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

c 类 static 函数 “类加载机制”详解(4)

电脑杂谈  发布时间:2018-02-16 16:47:30  来源:网络整理

『int i = 128』对应助记符“sipush”

“sipush”:表示将一个短整型常量值(-32768 ~ 32767)推送至栈顶

『int m = 1』对应助记符“iconst_1”

“iconst_1”:表示将int类型1推送至栈顶(iconst_m1 ~ iconst_5)

JVM为int的 -1 ~ 5 提供了 7 个助记符,分别是:’iconst_m1’、’iconst_0’、’iconst_1’、’iconst_2’、’iconst_3’、’iconst_4’、’iconst_5’

/**
 * -XX:+TraceClassLoading
 */
public class MyFinalTest {

    public static void main(String[] args) {
        System.out.println(MyClass2.num);
    }
}

class MyClass2 {

    public static final int num = new Random().nextInt(25);

    static {
        System.out.println("MyClass2 static block");
    }

}

结果:

MyClass2 static block
19

这里,MyClass2被初始化了,这是因为num的值在编译器是无法确定的,它不像上面的『public static final String str = “hello world”;』在编译期就已经能够确定这个str字段的值内容,并且str是类级别的属性(static),它被所有的实例对象共享,且该str字段是不可变的(final),从这两点(static final)编译器确定了str是一个“编译期可知的全局常量值”,因此就可以将其直接放到调用该字段的类的常量池中。而本例中,num的虽然也是“全局常量”,但是该常量的值在编译器是无法得知的,需要在运行时初始化MyClass2类时才能得到,所以这里会对MyClass2进行初始化。

关于接口的初始化:

a)当一个接口在初始化时,并不要求其父接口都完成了初始化。

b)在初始化一个类时,并不会先初始化它所实现的接口。

只有在真正使用到父接口的时候(如引用接口中所定义的常量时),才会初始化。

/**
 * -XX:+TraceClassLoading
 */
public class MyTest5 {

    public static void main(String[] args) {
        System.out.println(MyChild5.b);
    }
}

interface MyParent5 {

    int a = new Random().nextInt(56);
}

interface MyChild5 extends MyParent5 {
    int b = new Random().nextInt(25);
}
输出:

此时,通过追踪类加载信息打印日志可知’MyParent5’和‘MyChild5’两个类都被加载了。但是,此时被初始化的只有’MyChild5’类,而’MyParent5’仅是被加载了,并没有被初始化。

我们可通过HSDIS(JIT编译代码的反汇编插件)生成的汇编代码中可以发现,只有’MyChild5’类的初始化阶段被执行了(即,执行类构造器“<clint>()”方法的过程),而汇编代码中并没有’MyParent5’类的初始化执行指令。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-80669-4.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 萧微
      萧微

      美国是伊拉克战乱的始作俑者

    • 赵睿
      赵睿

      台湾是美帝种在中国大地上的一块烂肉

    热点图片
    拼命载入中...