前序文章:深入理解Java类加载

<clinit>()<init>() 区别

一、<clinit>()

Java 类加载的初始化过程中,编译器按语句在源文件中出现的顺序,依次自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并产生 <clinit>() 方法。 如果类中没有静态语句和静态代码块,那可以不生成 ()` 方法。

并且 <clinit>() 不需要显式调用父类(接口除外,接口不需要调用父接口的初始化方法,只有使用到父接口中的静态变量时才需要调用)的初始化方法 <clinit>(),虚拟机会保证在子类的 <clinit>() 方法执行之前,父类的 <clinit>() 方法已经执行完毕。

二、<init>()

对象构造时用以初始化对象的,构造器以及非静态初始化块中的代码。

<clinit>()<init>() 执行顺序

直接看代码

public class Test {
private static Test instance; static {
System.out.println("static开始");
// 下面这句编译器报错,非法向前引用
// System.out.println("x=" + x);
instance = new Test();
System.out.println("static结束");
} public Test() {
System.out.println("构造器开始");
System.out.println("x=" + x + ";y=" + y);
// 构造器可以访问声明于他们后面的静态变量
// 因为静态变量在类加载的准备阶段就已经分配内存并初始化0值了
// 此时 x=0,y=0
x++;
y++;
System.out.println("x=" + x + ";y=" + y);
System.out.println("构造器结束");
} public static int x = 6;
public static int y; public static Test getInstance() {
return instance;
} public static void main(String[] args) {
Test obj = Test.getInstance();
System.out.println("x=" + obj.x);
System.out.println("y=" + obj.y);
}
}

输出信息如下:

static开始
构造器开始
x=0;y=0
x=1;y=1
构造器结束
static结束
x=6
y=1

虚拟机首先执行的是类加载初始化过程中的 <clinit>() 方法,也就是静态变量赋值以及静态代码块中的代码,如果 <clinit>() 方法中触发了对象的初始化,也就是 <init>() 方法,那么会进入执行 <init>() 方法,执行 <init>() 方法完成之后,再回来继续执行 <clinit>() 方法。

上面代码中,先执行 static 代码块,此时调用了构造器,构造器中对类变量 x 和 y 进行加 1 ,之后继续完 static 代码块,接着执行下面的 public static int x = 6; 来重新给类变量 x 赋值为 6,因此,最后输出的是 x=6, y=1。

如果希望输出的是 x=7,y=1,很简单,将语句 public static int x = 6; 移至 static 代码块之前就可以了。

类加载之 <clinit>() 和 <init>()的更多相关文章

  1. clinit和init(转载)

    clinit和init(转载)   今天在看深入Java虚拟机的class文件结构时,看到了这么一句话, 可能出现在class文件中的两种编译器产生的方法是:实例初始化方法(名为<init> ...

  2. java执行顺序之深入理解clinit和init

    原文地址:https://blog.csdn.net/qq_36522306/article/details/80582758 前言: 最近研究了深入理解JVM这本书中的知识,对java中各部分执行的 ...

  3. <clinit>() 和 <init>()

    原文:https://www.cnblogs.com/aspirant/p/7200523.html <clinit>() 类构造器方法 在 类初始化阶段 被执行 由编译器自动收集类中的所 ...

  4. JVM思考-init和clinit区别

    JVM思考-init和clinit区别 目录:JVM总括:目录 clinit和init的区别其实也就是Class对象初始化对象初始化的区别,详情看我上一篇博客: JVM总括四-类加载过程.双亲委派模型 ...

  5. 深入理解jvm--Java中init和clinit区别完全解析(转)

    转自:http://blog.csdn.net/u013309870/article/details/72975536 init和clinit区别 ①init和clinit方法执行时机不同 init是 ...

  6. 深入理解java虚拟机(4)---类加载机制

    类加载的过程包括: 加载class到内存,数据校验,转换和解析,初始化,使用using和卸载unloading过程. 除了解析阶段,其他过程的顺序是固定的.解析可以放在初始化之后,目的就是为了支持动态 ...

  7. JVM总括四-类加载过程、双亲委派模型、对象实例化过程

    JVM总括四-类加载过程.双亲委派模型.对象实例化过程 目录:JVM总括:目录 一. 类加载过程 类加载过程就是将.class文件转化为Class对象,类实例化的过程,(User user = new ...

  8. JVM性能调优(1) —— JVM内存模型和类加载运行机制

    一.JVM内存模型 运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包.因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分 ...

  9. 深度分析:面试阿里,字节99%会被问到Java类加载机制和类加载器

    1. 类加载机制 所谓类加载机制就是JVM虚拟机把Class文件加载到内存,并对数据进行校验,转换解析和初始化,形成虚拟机可以直接使用的Jav类型,即Java.lang.Class. 2. 类加载的过 ...

随机推荐

  1. redis 集群模式

    redis cluster 介绍 自动将数据进行分片,每个 master 上放一部分数据 提供内置的高可用支持,部分 master 不可用时,还是可以继续工作的 在 redis cluster 架构下 ...

  2. 20191121-2 Final发布

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/10062 操作视频:https://www.bilibili.com/vi ...

  3. $CH$ $0x50$ & $0x51$ 做题记录

    [X]$Mr.Young's\ Picture\ Permutations$ 前面这儿写了挺多道辣,,,懒得写辣$QAQ$ (后面所有同上都是同这个$QwQ$ [X]$LCIS$ 做过了,看这儿 $u ...

  4. ReentrantLock 源码分析从入门到入土

    回答一个问题 在开始本篇文章的内容讲述前,先来回答我一个问题,为什么 JDK 提供一个 synchronized 关键字之后还要提供一个 Lock 锁,这不是多此一举吗?难道 JDK 设计人员都是沙雕 ...

  5. 对 Redux 一头雾水?看完这篇就懂了

    首先,学习 Redux 可能会很困难 当你终于学会了如何使用 React,也有了自己去构建一些应用的信心,那会是一种非常棒的感觉.你学会了管理状态,一切看起来井井有条.但是,很有可能这就到了你该学习 ...

  6. MacBook Pro 入手一年了,到底香不香?

    最近又有小伙伴问到底值不值得入手一台 MacBook Pro,松哥自己在 2018 年 10 月份的时候入手了一台,到现在为止,也用了一年多了,今天就来和小伙伴们聊一聊使用感受,至于到底值不值,需要大 ...

  7. leetcode腾讯精选练习之两数相加

    两数相加 题目: 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字.如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们 ...

  8. MapInfo常见数据格式

    在MapInfo 中所指的表是单纯的数据表或是图形与数据的结合.一个典型的MapInfo表将主要由*.tab.*.dat.*.wks.*.dbf.*.xls.*.map.*.id.*.ind文件格式组 ...

  9. echarts设置数据在轴线上显示

    项目中遇到数据需要在右侧显示,如图,直接上代码: 1.需要在哪个轴上显示  就把那个轴写成一个数组 2.分别设置一下定位和数据即可(如下图红色部分) yAxis: [ { type: 'categor ...

  10. python 生成器,迭代器,闭包,装饰器

    1.生成器,迭代器,闭包,装饰器的优点 生成器就是一类特殊的迭代器 迭代器的优点也即生成器的优点: 1.节约内存.python在使用生成器时对延迟操作提供了支持. 2.迭代到下一次的调用时,所使用的参 ...