Java类什么时候开始初始化

虚拟机规范严格规定了有且只有5种情况必须立即对类进行初始化。
1)遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
2)使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3)当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类初始化。
4)当虚拟机启动时,用户需要指定一个要执行的主类(包含main方法的),虚拟机会优先初始化这个主类。
5)当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic等时,这个方法的类还没有进行过初始化,则需要先触发其初始化。
在这里讲几个静态语句的例子,如:
public class ConstClass {
    static {
      System. out .println ( "ConstClass init!!!" );
   }
    public static final String HELLOWORLD = "hello world" ;
    public static final int num = 1;
}
public   class Test {
     public static void main(String[] args) {
           System. out .println( "" + ConstClass. num );
     }
}
 

最后的执行结果为:1,并没有输出ConstClass init!!!。
类Test虽然引用了类ConstClass的常量,但类ConstClass不会因为类Test的引用而初始化,因为类Test已经把类ConstClass中的常量num给引入到自己的常量池中了,所以类Test对类ConstClass常量的引用其实是对类Test自身的常量引用。
类的常量是在类的Class文件中定义的,位于魔数、版本号之后。
如果所ConstClass改为:
public class ConstClass {
    static {
      System. out .println ( "ConstClass init!!!" );
   }
    public static final String HELLOWORLD = "hello world" ;
    public static   int num = 1;
}
最后输出:
ConstClass init!!!
1
所以能看出必须是常量,不能只是静态的。
还有一种情况是子类跟父类的引用关系,如:
public class SuperClass {
    static {
      System. out .println ( "SuperClass init!!!" );
   }
    public static   int num = 123;
}
public class SubClass extends SuperClass{
    static {
      System. out .println ( "SubClass init!!!" );
   }
}
public static void main(String[] args) {
      System. out .println( "" + SubClass. num );
}
这时只输出
SuperClass init!!!
123
这是因为对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化,而不会触发子类的初始化。






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值