Java 类加载和实例化对象的过程

1. 类加载实例化过程

  1. 当我们编写完一个*.java类后。
  2. 编译器(如javac)会将其转化为字节码。
  3. 转化的字节码存储在.class后缀的文件中(.class 二进制文件)。
  4. 接下来在类的加载过程中虚拟机JVM利用ClassLoader读取该.class文件将其中的字节码加载到内存中。
  5. 基于这些字节码信息创建相应的Class Object.
  6. 每个类在JVM中只加载一次,故而每个类都对应着一个唯一的Class对象(Class Object).
  7. 这个对象包含了类的元信息(metadata),如类的名称、包名、父类、实现的接口、字段、方法、构造函数等。 
  8. class Objcect可以通过获取构造函数创建实例化的对象。

2. 类加载存储位置

  • 字节码文件:
    是Java源代码编译后的产物,它们以二进制的形式存储在文件系统中。 所以它并不存放于JVM的结构中。
  • Class Object:
    Class对象被存储在JVM的方法区(Method Area)中的元空间(Metaspace)里。
  • 实例化对象:
    存放于堆内存(Heap Memory) 

3.  JVM利用classloader进行类加载和类初始化的区别

在Java中,类加载(Class Loading)和类初始化(Class Initialization)是两个不同的阶段,它们在类生命周期中扮演着不同的角色。下面是这两个阶段的区别: 

  • 类加载(Loading):
    通过类的全名获取类的二进制数据。将这些数据转换成方法区的运行时数据结构。在内存中生成一个代表这个类的java.lang.Class对象,作为这个类的各种数据的入口。然而,类的初始化(即执行静态初始化代码和静态初始化块)是在类加载的最后阶段(初始化阶段)由 JVM 自行完成的。所以我们在使用类反射,如User.class 获取class对象时,它是不会去执行静态代码块的。
  • 类初始化(Class Initialization)
    类初始化,广义上将它类加载过程中的最后一步,只不过这一步是动态的,而不是由程序启动之初就加载的,只有当类被主动使用时才会发生。这个阶段会执行类的静态初始化代码(在声明类变量时指定的初始值和在静态代码块中指定的代码)。这个过程只会在JVM首次主动使用类时发生一次。

4. 结合第三点,补充说明为什么反射中Object.class 不加载静态代码块,而Class.forName("ClassName")会加载静态代码块 

Object.class 和 Class.forName("ClassName") 在触发类加载和初始化方面有不同的行为,这主要是因为它们使用的方式和上下文不同。

Object.class:
当你使用 Object.class 时,你实际上是在引用Java的根类Object的Class对象。由于Object类是Java运行时系统的一部分,并且它几乎总是在你开始执行任何Java代码之前就已经被加载和初始化了(因为其他所有的类都直接或间接地继承自Object类),所以当你引用Object.class时,它不会再次触发Object类的加载和初始化。 静态代码块只会在类首次被主动使用时执行,而由于Object类几乎总是已经在使用之前就被加载和初始化了,因此通过Object.class引用它不会再次触发静态代码块的执行。
Class.forName("ClassName"):
Class.forName("ClassName") 是一个用于动态加载类并触发其初始化的方法。当你调用这个方法并传入一个类名(作为字符串)时,JVM会尝试找到并加载这个类。如果类还没有被加载和初始化,JVM会首先加载这个类,然后触发其初始化过程,这包括执行静态代码块。 Class.forName() 方法的主要用途是在运行时动态地加载和使用类,而不需要在编译时就知道这个类的存在。由于它是在运行时动态加载类的,所以它总是会触发类的加载和初始化过程(如果类还没有被加载和初始化的话)。
总结来说,Object.class 不会运行静态代码块是因为Object类通常在你开始执行任何Java代码之前就已经被加载和初始化了,而Class.forName("ClassName") 会运行静态代码块是因为它用于在运行时动态地加载和初始化类。

5. 关于静态代码块初始化的几个关键点:

执行时机:静态代码块在类被加载到JVM时执行。这通常发生在类的第一次主动使用时,例如创建类的实例、访问类的静态字段或方法、反射调用类的方法等。 执行顺序:如果有多个静态代码块,它们将按照在源文件中出现的顺序执行。 与静态变量的关系:静态变量可以在静态代码块中初始化,也可以在声明时直接赋值。但是,如果静态变量在声明时直接赋值,那么该赋值操作会在静态代码块之前执行。 静态代码块与构造器:静态代码块在构造器之前执行。这是因为静态代码块属于类级别的初始化,而构造器属于对象级别的初始化。 线程安全:虽然静态代码块只执行一次,但在多线程环境下,JVM会确保静态代码块的线程安全性,即静态代码块会同步执行,不会被多个线程同时访问。但是,请注意,静态代码块中的代码本身并不是线程安全的,你仍然需要确保其中的代码在多线程环境下能够正确运行。 

6. 类中的静态代码块被初始化后保存在JVM的哪里?

在JVM中,类中的静态代码块(static code block)在初始化后被执行,但它们本身并不直接“保存”在JVM的某个特定区域。静态代码块中的代码逻辑在类加载时被执行一次,并且其执行结果(如静态变量的赋值)会被存储在JVM的以下区域:

  • 方法区(Method Area):
    类加载后,静态变量(包括在静态代码块中初始化的变量)会被存储在方法区中的静态变量区域。静态变量属于类变量,不属于对象实例的一部分,只会在类加载时初始化一次。
     
  • 堆内存(Heap Memory): 虽然静态代码块本身不直接存储在堆内存中,但是静态代码块中初始化的静态对象(如静态的数组、其他类的静态实例等)会存储在堆内存中。这些对象通过静态变量持有引用,静态变量则存储在方法区的静态变量区域中。
     
  • 常量池(Constant Pool):
    如果静态代码块中声明了static final常量,并且这些常量的值在编译时就能确定(即常量折叠),那么这些常量会被放入类的常量池中。常量池是方法区的一部分,用于存储编译期生成的各种字面量和符号引用。 需要注意的是,静态代码块只是类加载过程中的一个逻辑单元,用于在类加载时执行一些初始化操作。这些操作的结果(如静态变量的值)会被存储在JVM的相应区域中,而静态代码块本身并不作为一个独立的实体被保存。当类被加载并初始化后,静态代码块中的代码逻辑就完成了它的使命,后续的对象创建和方法调用都不会再次执行这些代码。 

7. java 类级别的初始化和对象级别的初始化的区别?

在Java中,类级别的初始化和对象级别的初始化是两个不同的概念,它们分别涉及类的静态部分和实例部分。以下是它们之间的主要区别:

类级别的初始化
执行时机:当类被JVM首次主动使用时,会触发类级别的初始化。这通常发生在创建类的第一个实例、访问类的静态字段或方法、或者通过反射调用类的方法等情况。
初始化内容:类级别的初始化包括执行静态代码块(static blocks)和初始化静态变量。静态代码块和静态变量的初始化顺序按照它们在源代码中出现的顺序进行。
执行次数:类级别的初始化只会在类首次被加载到JVM时执行一次,无论创建多少个类的实例,静态代码块都不会再次执行。
线程安全性:JVM会确保类级别的初始化是线程安全的,即静态代码块会同步执行,不会被多个线程同时访问。
对象级别的初始化
执行时机:当创建类的实例时,会触发对象级别的初始化。这通常通过调用类的构造函数来完成。
初始化内容:对象级别的初始化包括执行实例初始化块(instance blocks)和构造函数,以及初始化实例变量。实例初始化块和构造函数的执行顺序是:首先执行实例初始化块(按照它们在源代码中出现的顺序),然后执行构造函数。
执行次数:与类级别的初始化不同,对象级别的初始化会在每次创建类的实例时执行。
线程安全性:对象级别的初始化(即构造函数的执行)不是线程安全的。如果在多线程环境中创建类的实例,需要确保对共享资源的访问是同步的,以避免数据不一致或其他并发问题。
 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/840682.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GAW-1000D 微机控制钢绞线拉力试验机

一、整机外观图与示意图 外观示意图 性能说明: GAW-1000D型微机控制电液伺服钢绞线拉力试验机主要用于对预应力钢绞线进行抗拉强度测试。由宽调速范围的电液比例伺服阀与计算机及测控单元所组成伺服控制系统,能精确的控制和测量试验全过程。整机由主机…

Unity3D雨雪粒子特效(Particle System)

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、下雨的特效1-1.首先就是创建一个自带的粒子系统,整几张贴图,设置一下就能实现想要的效果了1-2 接着往下看视频效果 👉二、下雪的特效👉三、下雪有积雪的效果3-1 先把控…

docxtemplater避坑!!! 前端导出word怎么插入本地图片或base64 有完整示例

用docxtemplater库实现前端通过模板导出word,遇到需求,要插图片并转成word并导出,在图片转换这块遇到了问题,网上查示例大多都跑不通,自己琢磨半天,总算搞明白了。 附上清晰完整示例,供参考。 …

SpringCloudAlibaba:6.2RocketMQ的普通消息的使用

简介 普通消息也叫并发消息&#xff0c;是发送效率最高&#xff0c;使用最多的一种 依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSch…

【强化学习的数学原理-赵世钰】课程笔记(三)贝尔曼最优公式

目录 学习引用内容梗概1. 第三章主要有两个内容2. 第二章大纲 二.激励性实例&#xff08;Motivating examples&#xff09;三.最优策略&#xff08;optimal policy&#xff09;的定义四.贝尔曼最优公式&#xff08;BOE&#xff09;&#xff1a;简介五.贝尔曼最优公式&#xff0…

专为汽车内容打造的智能剪辑解决方案

汽车内容创作已成为越来越多车主和汽车爱好者热衷的活动。然而&#xff0c;如何高效、便捷地将行车途中的精彩瞬间转化为高质量的视频作品&#xff0c;一直是困扰着广大用户的一大难题。美摄科技凭借其深厚的视频处理技术和智能分析能力&#xff0c;推出了专为汽车内容记录而生…

C语言数据结构栈的概念及结构、栈的实现、栈的初始化、销毁栈、入栈、出栈、检查是否为空、获取栈顶元素、获取有效元素个数等的介绍

文章目录 前言栈的概念及结构栈的实现一、 栈结构创建二、 初始化结构三、销毁栈四、入栈五、出栈六、检查是否为空七、获取栈顶元素八、获取有效元素的个数九、测试 1十、测试 2总结 前言 C语言数据结构栈的概念及结构、栈的实现、栈的初始化、销毁栈、入栈、出栈、检查是否为…

意外发现openGauss兼容Oracle的几个条件表达式

意外发现openGauss兼容Oracle的几个条件表达式 最近工作中发现openGauss在兼容oracle模式下&#xff0c;可以兼容常用的两个表达式&#xff0c;因此就随手测试了一下。 查看数据库版本 [ommopenGauss ~]$ gsql -r gsql ((openGauss 6.0.0-RC1 build ed7f8e37) compiled at 2…

数据结构----堆的实现(附代码)

当大家看了鄙人的上一篇博客栈后&#xff0c;稍微猜一下应该知道鄙人下一篇想写的博客就是堆了吧。毕竟堆栈在C语言中常常是一起出现的。那么堆是什么&#xff0c;是如何实现的嘞。接下来我就带大家去尝试实现一下堆。 堆的含义 首先我们要写出一个堆&#xff0c;那么我们就需…

kubernetes之prometheus kube-controller-manager。 scheduler报错问题

项目场景&#xff1a; prometheus scheduler及kube-controller-manager监控报错 问题描述 kubeadm搭建完kube-prometheus 会有这个报错 原因分析&#xff1a; rootmaster2:~# kubectl describe servicemonitor -n kube-system kube-controller-manager通过以上图片我们发现 k…

php TP8 阿里云短信服务SDKV 2.0

安装&#xff1a;composer require alibabacloud/dysmsapi-20170525 2.0.24 官方文档&#xff1a;短信服务_SDK中心-阿里云OpenAPI开发者门户 (aliyun.com) 特别注意&#xff1a;传入参数获得值形式 正确&#xff1a; $PhoneNumbers $postData[PhoneNumbers];$signName $po…

单片机设计注意事项

1.电源线可以30mil走线&#xff0c;信号线可以6mil走线 2.LDO推荐 SGM2019-3.3,RT9013,RT9193,1117-3.3V。 3.单片机VCC要充分滤波后再供电&#xff0c;可以接0.1uf的电容 4.晶振附件不要走其他元件&#xff0c;且放置完单片机后就放置晶振&#xff0c;晶振靠近X1,X2。

【全网最全】2024电工杯数学建模A题前三题完整解答matlab+21页初步参考论文+py代码等(后续会更新成品论文)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片链接&#xff0c;那是获取资料的入口&#xff01; 【全网最全】2024电工杯数学建模A题前三题完整解答matlab21页初步参考论文py代码等&#xff08;后续会更新成品论文&#xff09;「首先来看看目前已有的…

二叉树—先后序线索化和先后序线索遍历

有了上篇文章的基础&#xff0c;先序和后序的线索化逻辑一样。 代码如下&#xff1a; void preOrderThreadTree(TreeNode* T,TreeNode** pre) {if (T NULL) {;}else {//printf("%c ", T->val);if (T->lchild NULL) {T->ltag 1;T->lchild *pre;}if …

7款好用到离谱的神级App推荐!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 转眼间&#xff0c;2024年已经是下个月。最近有很多小伙伴的咨询&#xff0c;我也赶紧整理了7款好用的软件&#xff0c;希望对大家有所帮助。 …

Git简介以及下载安装和配置

Git介绍 什么是版本控制?什么是Git?什么是集中式版本控制(了解)分布式版本控制工作流程 Git的安装与配置注册邮箱以及用户名(方便远程使用)初始化项目Git在ideal上的使用(本地) 什么是版本控制? ​ 版本控制是指对软件开发过程中各种程序代码,控制文件及说明文档等文件变更…

清理mysql binglog文件

mysql随着使用时间的推移&#xff0c;binglog文件会越来越大&#xff0c;比如我们的oa系统&#xff0c;上线4年多了&#xff0c;最近总有磁盘空间满影响系统正常使用的情况出现。检查后发现binglog是罪归祸首。 binglog文件最好不要采用应删除的方式清理&#xff0c;如下方式可…

spring cache(三)demo

一、入门demo 1、pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.o…

ACL组网实验(华为)

思科设备参考&#xff1a;ACL组网实验&#xff08;思科&#xff09; 更多内容参考&#xff1a;华为ACL配置&#xff08;基本ACL高级ACL综合应用&#xff09; 技术简介 ACL&#xff08;Access Control List&#xff09;技术是一种基于包过滤的流控制技术&#xff0c;主要用于…