当前位置:主页 > java教程 > 详谈jvm--Java中init和clinit的区别

jvm--Java中init和clinit的区别点整理

发布:2020-01-21 09:07:37 112


给网友们整理java相关的编程文章,网友邓智鑫根据主题投稿了本篇教程内容,涉及到jvm、java、init、clinit、详谈jvm--Java中init和clinit的区别相关内容,已被900网友关注,如果对知识点想更进一步了解可以在下方电子资料中获取。

详谈jvm--Java中init和clinit的区别

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(); // <clinit>
  private int x = 1;  // <init>
  X(){
   // <init>
  }
  static {
   // <clinit>
  }
}

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的区别就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持码农之家。


参考资料

相关文章

  • java面试LruCache 和 LinkedHashMap及算法实现

    发布:2023-04-01

    这篇文章主要为大家介绍了java面试LruCache 和 LinkedHashMap及算法实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪


  • JavaScript表达式和语句知识点整理

    发布:2020-01-20

    下面小编就为大家带来一篇JavaScript学习笔记整理_关于表达式和语句。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧


  • 详解Java String字符串获取每一个字符及常用方法

    详解Java String字符串获取每一个字符及常用方法

    发布:2022-09-23

    给网友朋友们带来一篇关于Java String的教程,这篇文章主要介绍了详解Java String字符串获取每一个字符及常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学


  • 介绍Java模板引擎性能对比

    发布:2020-01-27

    本篇文章主要介绍了浅谈Java模板引擎性能对比 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧


  • 实现JavaScript评论点赞功能的方法步骤

    发布:2020-01-29

    通过分析评论功能的逻辑关系,学会如何使用JavaScript实现评论、回复、点赞等各种功能。这篇文章主要介绍了JavaScript评论点赞功能的实现方法,需要的朋友可以参考下


  • javascript prototype原型知识点总结

    发布:2020-01-04

    prototype原型是javascript中特别重要的概念,属于必须要掌握,如果没有良好的掌握的话,进一步用好或者学好js基本是不可能的实现的事情,并且此概念稍有难度,可能对于初次接触的朋友来说有


  • Java线程生命周期图文详细讲解

    发布:2023-04-22

    在java中,任何对象都要有生命周期,线程也不例外,它也有自己的生命周期。线程的整个生命周期可以分为5个阶段,分别是新建状态、就绪状态、运行状态、阻塞状态和死亡状态


  • java中float与double的不同点整理

    发布:2020-06-13

    这篇文章主要介绍了JAVA中float与double的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧


网友讨论