前序文章:深入理解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. 我的 2019 年 Python 文章榜单

    现在是 2020 年的第一天,我相信从昨天开始,各位的信息流里肯定充斥了各式各样的年度盘点/回顾/总结/记录之类的内容.虽然来得稍晚了,但我还是想给诸位送上这一篇文章. 我将在本文中列出自己于 201 ...

  2. 天猫SSM项目学习记录(一)----第一个相对完整的SSM项目

    来源:  http://how2j.cn/k/tmall_ssm/tmall_ssm-1516/1516.html?p=78908 目的:记录一个相对完整的SSM项目模板 1.工具:idea2018商 ...

  3. DecoratorPattern(装饰器模式)-----Java/.Net

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装

  4. 1049 数列的片段和 (20 分)C语言

    给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列 { 0.1, 0.2, 0.3, 0.4 },我们有 (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) ...

  5. Vue+Vant+Vuex实现本地购物车功能

    通常,我们做移动端商城的时候,通常会有购物车模块,那购物车模块有两种实现方式,一是储存在后台通过接口获取到购物车信息,二是存在用户手机本地,第一种方法只要调用接口获取比较简单,这里介绍的是第二种方法, ...

  6. spring之为什么要使用AOP(面向切片编程)?

    需求1-日志:在程序执行期间追踪正在发生的活动: 需求2-验证:希望计算器只处理正数的运算: 一.普通方法实现 Calculator.java package com.gong.spring.aop. ...

  7. 克隆linux系统后,将eth1修改成eth0

    使用VMware克隆的linux系统之后,发现网卡信息只有eth1,却没有eth0.将eth1修改成eth0. 1.vi /etc/udev/rules.d/70-persistent-net.rul ...

  8. 微信生成二维码 PHP

    <?php /** * Created by PhpStorm. * User: liyiming * Date: 2019/8/8 * Time: 14:23 */ # 生成二维码 class ...

  9. .sarut后缀病毒,勒索病毒

    前两天朋友的电脑中所有的文件后缀名都被改为.sarut 一看就是中了勒索病毒 每个文件夹下都有一个勒索信 查资料后发现这个病毒是STOP病毒的变种 可能是朋友使用windows激活工具了,然后这个病毒 ...

  10. Win10系统下MySQL压缩版安装配置教程

    MySQL分为安装版和压缩.为了以后MySQL出问题想重装时的各种不必要的麻烦,我个人推荐压缩版MySQL.下面进入教程: 进入官网下载MySQL压缩包,并解压如下 配置环境变量---将bin文件的目 ...