`

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

    博客分类:
  • j2se
阅读更多

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
 }
 
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics