init和clinit区别

①init和clinit方法执行时机不同

init是对象构造器方法,也就是说在程序执行 new 一个对象调用该对象类的 constructor 方法时才会执行init方法,而clinit是类构造器方法,也就是在jvm进行类加载—–验证—-解析—–初始化,中的初始化阶段jvm会调用clinit方法。

②init和clinit方法执行目的不同

init is the (or one of the) constructor(s) for the instance, and non-static field initialization.

clinit are the static initialization blocks for the class, and static field initialization.

上面这两句是Stack Overflow上的解析,很清楚init是instance实例构造器,对非静态变量解析初始化,而clinit是class类构造器对静态变量,静态代码块进行初始化。看看下面的这段程序就很清楚了。

class X {

static Log log = LogFactory.getLog(); //

private int x = 1; //

X(){

//

}

static {

//

}

}

clinit详解

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

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

public class Test{

static{

i=0;//给变量赋值可以正常编译通过

System.out.print(i);//这句编译器会提示"非法向前引用"

}

static int i=1;

}

②虚拟机会保证在子类的<clinit>()方法执行之前,父类的<clinit>()方法已经执行完毕。 因此在虚拟机中第一个被执行的<clinit>()方法的类肯定是java.lang.Object。由于父类的<clinit>()方法先执行,也就意味着父类中定义的静态语句块要优先于子类的变量赋值操作,如下代码中,字段B的值将会是2而不是1。

static class Parent{

public static int A=1;

static{

A=2;}

static class Sub extends Parent{

public static int B=A;

}

public static void main(String[]args){

System.out.println(Sub.B);

}

}

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

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

以上这篇详谈jvm--Java中init和clinit的区别就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

init.x java_详谈jvm--Java中init和clinit的区别相关推荐

  1. 【java】深入理解Java JVM虚拟机中init和clinit的区别

    1.概述 转载并且补充:深入理解Java JVM虚拟机中init和clinit的区别 原创 之所以来转载一下,是因为,有个学弟问了这个问题 这个知识点,回顾起来应该是我看 深入理解Java JVM虚拟 ...

  2. java is instance of_详谈Java中instanceof和isInstance的区别

    一次性搞定instanceof和isInstance,instanceof和isInstance长的非常像,用法也很类似,先看看这两个的用法: obj.instanceof(class) 也就是说这个 ...

  3. throws java_基于Java中throw和throws的区别(详解)

    系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 ...

  4. JAVA中堆和栈的区别和联系

    一.Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存. 堆:主要用于储存实例化的对象,数组.由JVM动态分配内存空间.一个JVM只有一个堆内存,线程是可以共享数据的. 栈 ...

  5. java中的异常种类和区别以及处理机制和区别

    java中的异常种类和区别以及处理机制和区别 按照异常需要处理的时机分为编译时异常(也叫强制性异常)也叫 CheckedException 和运行时异常(也叫非强制性异常)也叫 RuntimeExce ...

  6. java中ArrayList和LinkedList的区别

    首先来看ArrayList和LinkedList的集成类和接口的区别.// lang java public class ArrayList<E> extends AbstractList ...

  7. java中Runnable和Callable的区别

    文章目录 运行机制 返回值的不同 Exception处理 java中Runnable和Callable的区别 在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是ja ...

  8. java中wait和sleep的区别

    文章目录 Wait和sleep的区别 唤醒wait和sleep java中wait和sleep的区别 在本篇文章中,我们将会讨论一下java中wait()和sleep()方法的区别.并讨论一下怎么使用 ...

  9. java throw与throws_基于Java中throw和throws的区别(详解)

    系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 ...

  10. Java中重载和复写的区别

    Java中重载和复写的区别 重载(overload) 复写(override) 区别和联系 重载(overload) 函数重载的最突出的例子就是类的构造函数,用户定义一个对象时可能会提供多种参数组合: ...

最新文章

  1. 吴恩达神经网络和深度学习——第四周笔记
  2. SD-WAN行业发展需要VNF演进
  3. dede列表分页php,dede列表页分页英文调用方法
  4. 六、最通俗易懂的JavaScript进阶教程(二)
  5. python求最小值不能使用min和sotred_python基础——内置函数
  6. Java构造时成员初始化的陷阱
  7. 小米台灯底座接口很松_小米黑科技,AirPods和小米10 Pro伴侣,ZMI无线充蓝牙音箱体验...
  8. 模拟游戏--艾伦·图灵的传奇人生
  9. 网站或APP小程序调用短信验证码接口的流程
  10. 杭州-千岛湖(入门篇骑行)
  11. IC设计职位详解之“数字前端设计工程师”就业必学课程
  12. 【定时自动清理磁盘空间】
  13. CentOS 8.3.2011 镜像在PC上安装选择安装源时提示:设置基础软件仓库时出错
  14. INS/GNSS组合导航(一)全球导航卫星系统对比
  15. 使用阿里云建站 ——记录踩过的坑
  16. 【微信小程序】上传头像
  17. 咸鱼ZTMR实例—寻迹模块
  18. 【软件安装】SPSS22.0安装
  19. 【H.264/AVC视频编解码技术详解】八、 熵编码算法(2):H.264中的熵编码基本方法、指数哥伦布编码
  20. php框架 三维图展示,HTML5开发实例-3D全景(ThreeJs全景Demo) 详解(图)

热门文章

  1. win11非活动窗口如何设置 Windows11设置非活动窗口的步骤方法
  2. Android:Android SDK的下载与安装
  3. mysql 授权 失败_完美解决mysql客户端授权后连接失败的问题
  4. 电脑小写字母怎么切换_笔记本键盘切换的操作流程
  5. 1470. 重新排列数组
  6. 洛谷——P1075 [NOIP2012 普及组] 质因数分解
  7. 操作元素-改变元素内容
  8. 行内块的巧妙运用(HTML、CSS)
  9. opencv之求轮廓的凸包
  10. html取消重复,减少重复的HTML代码