读书人

深入java虚拟机 编译恒量、ClassLoade

发布时间: 2012-10-26 10:30:59 作者: rapoo

深入java虚拟机 编译常量、ClassLoader类、系统类加载器深度探析

import java.util.Random;

class test1{
?public static final int x = 6/2;
?static {
??System.out.println("test1 static block");
?}
}
class test2{
?public static final int x = new Random().nextInt();
?static {
??System.out.println("test2 static block");
?}
}
public class Demo {
?public static void main(String[] args) {
??System.out.println("-------打印test1x---------");
??System.out.println(test1.x);
??System.out.println("-------打印test2x---------");
??System.out.println(test2.x);
?}
}
运行结果:

-------打印test1x---------
3
-------打印test2x---------
test2 static block
1398792214

为什么第二个打印静态代码块第一个没打印呢?原因是这样的test1里的x是编译时的常量不会对类进行初始化而test2中不是编译时常量 会对类进行初始化 所谓编译时常量就是指编译时就能确定它的值

?

当类初始化时 首先去初始化他的直接父类或间接父类 父类初始化完了 然后在初始化 但不会初始化实现的接口?该类本身

当初始化一个接口的时候不回去初始化它的父接口

?

package com.cn;

class Parent {
?public static final int a = 3;
?static {
??System.out.println("parent static block");
?}
}

class Child extends Parent{
?public static final int b = 4;
?static {
??System.out.println("child static block");
?}
}
public class J2SETest{
?//这个静态代码会首先被执行
?static {
??System.out.println("J2SETest static block");
?}
?public static void main(String[] args) {
??//执行这句话时是不会对Parent进行初始化的 因为只是对变量进行声明 并没有产生对象 只有 对类进行主动调用时才会被初始化
??Parent parent ;
??//这句话会对Parent进行初始化
??parent = new Parent();
??System.out.println(parent.a);
??//这句话会首先去初始化父类? 但父类在new Parent()这条语句时已经被初始化了
??//所以不用重新初始化父类 而是直接初始化Child 但这只限于该Parent只被一个类加载器加载 如果被另一个加载器加载 会被重新初始化
??//下面这条语句也是对Chid的主动调用? 但b的值是编译时常量 在编译时它的值都已经确定了 所以Child里的静态代码块是不会被执行的
??System.out.println(Child.b);
??//现在大家可以猜一猜它的运行结果
??
??//预测运行结果是:
??//1. J2SETest static block
??//2. parent static block
??//3. 3
??//4. 4
?}
?
}

读书人网 >编程

热点推荐