Java类加载的过程详解

目录
  • Java:类加载过程
  • 1.加载——3件事
  • 2.连接
    • 2.1.验证
    • 2.2.准备
    • 2.3.解析
  • 3.初始化
  • 总结

Java:类加载过程

1.加载——3件事

  • 1.通过全类名获取定义此类的二进制字节流(eg:从jar、war中获取);
  • 2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构;
  • 3.在内存中生成一个代表该类的Class对象,作为方法区这些数据的访问入口。

2.连接

加载阶段和连接阶段的部分内容是交叉进行的,加载尚未结束,连接阶段可能就开始运行了。

2.1.验证

2.2.准备

准备阶段:正式为类变量分配内存并设置类变量初始值的阶段,这些内存在方法区分配。注意:

1.这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在 Java 堆中;

2.除了含有final修饰的变量外,其他都赋值0,null,false这种的。

如下例子, value 的值就被复制为 111,而不是0.

public static final int value=111

2.3.解析

解析阶段是虚拟机将常量池中的符号引用替换为直接引用的过程。

  • 也就是得到类或者字段、方法在内存中的指针或者偏移量。

什么是符号引用?

* 比如org.simple.People类引用了org.simple.Language类;

* 在编译时People类并不知道Language类的实际内存地址,因此只能使用符号org.simple.Language

3.初始化

初始化是类加载的最后一步,也是真正执行类中定义的 Java 程序代码(字节码),初始化阶段是执行类构造器 < clinit >() 方法的过程。

对于< clinit >() 方法的调用,虚拟机会自己确保其在多线程环境中的安全性。因为 < clinit >() 方法是带锁线程安全,所以在多线程环境下进行类初始化的话可能会引起死锁,并且这种死锁很难被发现。

对于初始化阶段,虚拟机严格规范了有且只有5中情况下,必须对类进行初始化:

  • 当遇到 new 、 getstatic、putstatic或invokestatic 这4条直接码指令时,比如 new 一个类,读取一个静态字段(未被 final 修饰)、或调用一个类的静态方法时。
  • 使用 java.lang.reflect 包的方法对类进行反射调用时 ,如果类没初始化,需要触发其初始化.
  • 初始化一个类,如果其父类还未初始化,则先触发该父类的初始化。
  • 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main 方法的那个类),虚拟机会先初始化这个类。
  • 当使用 JDK1.7 的动态动态语言时,如果一个 MethodHandle 实例的最后解析结构为 REF_getStaticREF_putStaticREF_invokeStatic、的方法句柄,并且这个句柄没有初始化,则需要先触发器初始化。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 一篇文章带你深入了解Java类加载

    目录 1.类加载 <1>.父子类执行的顺序 <2>类加载的时机 <3>类的生命周期 <4>类加载的过程 <5>类加载器 1.启动类加载器(BootstrapClassLoader) 2.扩展类加载器(ExtClassLoader) 3.应用程序类加载器(AppClassLoader) 4.2 自定义加载器 <6>类加载机制--双亲委派模型 总结 1.类加载 <1>.父子类执行的顺序 1.父类的静态变量和静态代码块(书写顺序

  • 分析Java中的类加载问题

    目录 一.Java类的加载顺序 二.类加载过程 三.被动引用中和类静态初始化的关系 四.类加载器双亲委派 一.Java类的加载顺序 引用1个网上的经典例子,并做稍许改动,以便大家更好地理解. public class Animal { private int i = test(); private static int j = method(); static { System.out.println("a"); } Animal(){ System.out.println("

  • 浅谈Java类的加载,链接及初始化

    一 类生命周期 Loading Linking(Verification.Preparation.Resolution) Initializing 二 类加载器 1 图解 2 代码 package jvm; public class T002_ClassLoadLevel { public static void main(String[] args) { System.out.println(String.class.getClassLoader()); System.out.println(

  • Java之类加载机制案例讲解

    1.类加载 <1>.父子类执行的顺序 1.父类的静态变量和静态代码块(书写顺序) 2.子类的静态变量和静态代码块(书写顺序) 3.父类的实例代码块(书写顺序) 4.父类的成员变量和构造方法 5.子类的实例代码块 6.子类的成员变量和构造方法 <2>类加载的时机 如果类没有进行初始化,则需要先进行初始化,虚拟机规范则是严格规定有且只有5种情况必须先对类进行初始化(而加载,验证,准备要在这个之前开始) 1.创建类的实例(new的方式),访问某个类的静态变量,或者对该静态变量赋值,调用类

  • Java三个类加载器及它们的相互关系

    一.什么是类加载器? 虚拟机设计团队把类加载阶段中的"通过一个类的全限定名来获取描述此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为"类加载器" 类加载器可以说是Java语言的一项创新,也是Java语言流行的重要原因之一,它最初是为了满足Java Applet的需求而开发出来的.虽然目前Java Applet技术基本上已经"死掉",但类加载器却在类层次划分.OSGi.

  • java类加载相关知识总结

    类加载器 类加载器作用 负责将.class文件(存储的物理文件)加载到内存中 类加载器过程 加载:通过全类名获取这个类准备用流传输,加载进内存,加载完毕创建一个Class对象 链接 验证:确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全 (文件中的信息是否符合虚拟机规范有没有安全隐患)准备:负责为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值 (初始化静态变量)解析:将类的二进制数据流中的符号引用替换为直接引用 (本类中如果用到了其他类,此

  • 详解Java类动态加载和热替换

    前言 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次加载后,会长期留驻JVM,直到JVM退出.这个说法,是不是正确的? 2) 在开发的一个集成平台中,需要集成类似接口的多种工具,并且工具可能会有新增,同时在不同的环境部署会有裁剪(例如对外提供服务的应用,不能提供特定的采购的工具),如何才能更好地实现? 针对上面的第2点,我们采用Java插件化开发实现.上面的两个问题,都和Java的类加载和热替换机制有关. 1. Java的类加载器和双亲委派模

  • Java类加载的过程详解

    目录 Java:类加载过程 1.加载--3件事 2.连接 2.1.验证 2.2.准备 2.3.解析 3.初始化 总结 Java:类加载过程 1.加载--3件事 1.通过全类名获取定义此类的二进制字节流(eg:从jar.war中获取): 2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构: 3.在内存中生成一个代表该类的Class对象,作为方法区这些数据的访问入口. 2.连接 加载阶段和连接阶段的部分内容是交叉进行的,加载尚未结束,连接阶段可能就开始运行了. 2.1.验证 2.2.准备

  • Java NIO Buffer过程详解

    前言 在与NIO通道交互时使用Java NIO Buffer. 如您所知,数据从通道读入缓冲区,并从缓冲区写入通道. 缓冲区本质上是一个可以写入数据的内存块,然后可以再次读取. 此内存块包含在NIO Buffer对象中,该对象提供了一组方法,可以更轻松地使用内存块. 基本缓冲区用法 使用缓冲区读取和写入数据通常遵循这4个小步骤: 1.写入数据到缓冲区 2.调用 buffer.flip() 3.从缓冲区读取数据 4.调用 buffer.clear() 或者 buffer.compact() 当你将

  • docker搭建minio及java sdk使用过程详解

    目录 1minio简洁 2 docker搭建minio 2.1 单节点 2.2 多节点部署 3 java sdk使用minio 1minio简洁 MinIO 是一款高性能.分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件.即X86等低成本机器也能够很好的运行MinIO. MinIO与传统的存储和其他的对象存储不同的是:它一开始就针对性能要求更高的私有云标准进行软件架构设计.因为MinIO一开始就只为对象存储而设计.所以他采用了更易用的方式进行设计,它能实现对象存储所需要的

  • java通过Jsoup爬取网页过程详解

    这篇文章主要介绍了java通过Jsoup爬取网页过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一,导入依赖 <!--java爬虫--> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.10.3</version> </depe

  • Java并发编程预防死锁过程详解

    这篇文章主要介绍了Java并发编程预防死锁过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在java并发编程领域已经有技术大咖总结出了发生死锁的条件,只有四个条件都发生时才会出现死锁: 1.互斥,共享资源X和Y只能被一个线程占用 2.占有且等待,线程T1已经取得共享资源X,在等待共享资源Y的时候,不释放共享资源X 3.不可抢占,其他线程不能强行抢占线程T1占有的资源 4.循环等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有

  • java property配置文件管理工具框架过程详解

    这篇文章主要介绍了java property配置文件管理工具框架过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 property property 是 java 实现的 property 框架. 特点 优雅地进行属性文件的读取和更新 写入属性文件后属性不乱序 灵活定义编码信息 使用 OO 的方式操作 property 文件 支持多级对象引用 快速开始 环境依赖 Maven 3.x Jdk 1.7+ Maven 引入依赖 <depende

  • Jmeter调用java脚本过程详解

    这篇文章主要介绍了Jmeter调用java脚本过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 jmeter为纯java编写,所以有三种方式使用java脚本,分别是:调用 .java 文件:调用 .class文件 :调用 .jar 文件 1. jmeter调用.java文件 1>. 新建一java脚本,内容如下: 2>. 新建线程组>>添加BeanShell Sampler.Debug PostProcessor.查看结果树

  • JAVA DOM解析XML文件过程详解

    这篇文章主要介绍了JAVA DOM解析XML文件过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 import java.io.IOException; import javax.xml.parsers.*; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.No

  • Java判断用户名和密码是否符合要求过程详解

    这篇文章主要介绍了Java判断用户名和密码过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 假设在某仓库管理系统的登录界面中需要输入用户名和密码,其中用户名只能由 6~10 位数字组成,密码只能有 6 位,任何不符合用户名或者密码要求的情况都视为异常,并且需要捕获并处理该异常. 下面使用自定义异常类来完成对用户登录信息的验证功能,实现步骤如下. (1) 编写自定义异常类 LoginException,该类继承自 Exception.在 L

  • java转换时区时间过程详解

    这篇文章主要介绍了java转换时区时间过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一丶时区 由于世界各国家与地区经度不同,地方时也有所不同,因此会划分为不同的时区. 地球是自西向东自转,东边比西边先看到太阳,东边的时间也比西边的早.东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算,这给人们带来不便. 为了克服时间上的混乱,1884年在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东.西

随机推荐