前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从JVM 源码看init和clinit到底什么区别

从JVM 源码看init和clinit到底什么区别

作者头像
JavaEdge
发布2020-05-26 16:52:52
8510
发布2020-05-26 16:52:52
举报
文章被收录于专栏:JavaEdgeJavaEdge

JVM 源码,都是初始化方法

1 执行时机

  • init是构造器时
  • clinit是类构造器时,也就是在类加载—–验证—-解析—–初始化,中的初始化阶段jvm调用clinit方法

2 执行目的

看 JVM 源码:

is_static是啥?

  • init是instance实例构造器,对非静态变量解析初始化
  • clinit是class类构造器对静态变量,静态代码块进行初始化

3 clinit详解

准备阶段,变量已经赋过一次系统要求的初始值 在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源,或者可以从另外一个角度来表达:初始化阶段是执行类构造器<clinit>方法的过程。

<clinit>方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的,静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问

虚拟机会保证在子类的<clinit>方法执行之前,父类的<clinit>方法已经执行完毕。 因此在虚拟机中第一个被执行的<clinit>方法的类肯定是java.lang.Object。意味着父类中定义的静态语句块要优先于子类的变量赋值操作

接口中不能使用静态语句块,但仍有变量初始化的赋值,因此接口与类一样都会生成<clinit>方法。 不同的是,执行接口的<clinit>方法不需要先执行父接口的<clinit>方法。 只有当父接口中定义的变量使用时,父接口才会初始化。 另外,接口的实现类在初始化时也一样不会执行接口的<clinit>方法。

接口中的属性都是static final类型的常量,因此在准备阶段就已经初始化

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 执行时机
  • 2 执行目的
  • 3 clinit详解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档