1 对象的实例化过程

  • 对象的实例化过程是分成两部分:类的加载初始化,对象的初始化
  • 要创建类的对象实例需要先加载并初始化该类,main方法所在的类需要先加载和初始化
  • 类初始化就是执行<clinit>方法,对象实例化是执行<init>方法
  • 一个子类要初始化需要先初始化父类

2 类的加载过程

  • 类的加载机制:如果没有相应类的class,则加载class到方法区。对应着加载->验证->准备->解析–>初始化阶段

    • 加载:载入class对象,不一定是从class文件获取,可以是jar包,或者动态生成的class
    • 验证:校验class字节流是否符合当前jvm规范
    • 准备:为类变量分配内存并设置变量的初始值(默认值)。如果是final修饰的对象则是赋值声明值
    • 解析:将常量池的符号引用替换为直接引用
    • 初始化:执行类构造器<client>(注意不是对象构造器),为类变量赋值,执行静态代码块。jvm会保证子类的<client>执行之前,父类的<client>先执行完毕
  • 其中验证、准备、解析3个部分称为 连接
  • <clinit>方法由静态变量赋值代码和静态代码块组成;先执行类静态变量显示赋值代码,再到静态代码块代码

3 触发类加载的条件

  • 第一次创建类的新对象时,会触发类的加载初始化和对象的初始化函数<init>执行,这个是实例初始化,其他6个都是类初始化
  • JVM启动时会先加载初始化包含main方法的类
  • 调用类的静态方法(如执行invokestatic指令)
  • 对类或接口的静态字段执行读写操作(即执行getstatic、putstatic指令);不过final修饰的静态字段的除外(已经赋值,String和基本类型,不包含包装类型),它被初始化为一个编译时常量表达式
    • 注意:操作静态字段时,只有直接定义这个字段的类才会被初始化;如通过其子类来操作父类中定义的静态字段,只会触发父类<clinit>的初始化而不是子类的初始化
  • 调用JavaAPI中的反射方法时(比调用java.lang.Class中的方法(Class.forName),或者java.lang.reflect包中其他类的方法)
  • 当初始化一个类时,其父类没有初始化,则需先触发父类的初始化(接口例外)

4 对象的实例化过程

  • 对象实例化过程 其实就是执行类构造函数 对应在字节码文件中的<init>()方法(称之为实例构造器);<init>()方法由非静态变量、非静态代码块以及对应的构造器组成

    • <init>()方法可以重载多个,类有几个构造器就有几个<init>()方法
    • <init>()方法中的代码执行顺序为:父类变量初始化,父类代码块,父类构造器,子类变量初始化,子类代码块,子类构造器。
  • 静态变量,静态代码块,普通变量,普通代码块,构造器的执行顺序

  • 具有父类的子类的实例化顺序如下

5 类加载器和双亲委派规则,如何打破双亲委派规则

  • 类加载器

    • 通过一个类的全限定名来获取描述此类的二进制字节流,实现这个动作的代码模块称为类加载器
    • 任意一个类都需要其加载器和类本身来确定类在JVM的唯一性;每个类加载器都有自己的类名称空间,同一个类class由不同的加载器加载,则被JVM判断为不同的类

  • 双亲委派模型
    • 启动类加载器有C++代码实现,是虚拟机的一部分。负责加载\lib下的类库
    • 其他的类加载器有java语言实现,独立于JVM,并且继承ClassLoader
    • extention ClassLoader负责加载\lib\ext目录下的类库
    • application ClassLoader 负责加载用户路径下(ClassPath)的代码
    • 不同的类加载器加载同一个class文件会导致出现两个类。而java给出解决方法是下层的加载器加委托上级的加载器去加载类,如果父类无法加载(在自己负责的目录找不到对应的类),而交还下层类加载器去加载。如下图

  • 打破双亲委派模型
    • 双亲委派模型并不是一个强制的约束模型,而是java设计者推荐给开发者的类加载实现方式
    • 双亲委派模型很好的解决各个类加载基础类的同一问题(越基础的类由越上层的加载器加载),但是基础类总是作为用户代码调用的API,但是如果它的具体实现是下层的代码,此时基础类需要调用下层的代码,则需要打破双亲委派模型
    • 如JNDI服务,JNDI的代码有启动类去加载(rt.jar),它需要调用由独立厂商部署在应用程序classpath下的JNDI的SPI(Service Provider Interface)代码。为了解决SPI代码加载问题,java引入了线程上下文类加载器去加载SPI代码。也就是父类加载器请求子类去完成类的加载动作
    • 线程上下文类加载器,线程创建时会从父线程继承,如果全局范围没有设置过,则默认设置为application Class Loader

欢迎指正文中错误

关注公众号,一起交流

参考文章

基础篇:详解JAVA对象实例化过程的更多相关文章

  1. Java 基础之详解 Java 反射机制

    一.什么是 Java 的反射机制?   反射(Reflection)是Java的高级特性之一,是框架实现的基础,定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: ...

  2. 图文详解Java对象内存布局

    作为一名Java程序员,我们在日常工作中使用这款面向对象的编程语言时,做的最频繁的操作大概就是去创建一个个的对象了.对象的创建方式虽然有很多,可以通过new.反射.clone.反序列化等不同方式来创建 ...

  3. 【Java】详解java对象的序列化

    目录结构: contents structure [+] 序列化的含义和意义 使用对象流实现序列化 对象引用的序列化 自定义序列化 采用实现Serializable接口实现序列化 采用实现Extern ...

  4. Java 基础之详解 Java IO

    Java IO基本概念 Java IO:即Java输入/输出系统,区分Java的输入和输出:把自己当成程序, 当你从外边读数据到自己这里就用输入(InputStream/Reader), 向外边写数据 ...

  5. java提高篇-----详解java的四舍五入与保留位

    转载:http://blog.csdn.net/chenssy/article/details/12719811 四舍五入是我们小学的数学问题,这个问题对于我们程序猿来说就类似于1到10的加减乘除那么 ...

  6. JavaScript基础篇详解

    全部的数据类型: 基本数据类型: undefined Number Boolean null String 复杂数据类型: object ①Undefined: >>>声明但未初始化 ...

  7. Python基础知识详解 从入门到精通(七)类与对象

    本篇主要是介绍python,内容可先看目录其他基础知识详解,欢迎查看本人的其他文章Python基础知识详解 从入门到精通(一)介绍Python基础知识详解 从入门到精通(二)基础Python基础知识详 ...

  8. java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的

    本文将详解java中的异常和异常处理机制 异常简介 什么是异常? 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常. Java异常的分类和类结构图 1.Java中的所 ...

  9. Java对象实例化的过程

    1.先为对象分配空间,并按属性类型默认初始化 ps:八种基本数据类型,按照默认方式初始化,其他数据类型默认为null 2.父类属性的初始化(包括代码块,和属性按照代码顺序进行初始化) 3.父类构造函数 ...

随机推荐

  1. 从《三体》到“中美科技战”,3分钟理解“网络”D丝为什么要迎娶“算力”白富美

    摘要:在多维的世界里,高维的文明对于低维文明具有碾压的优势,而网络也正在从二维走向三维!网络硬件的竞争主要是“芯片+算法”. 从三体到中美科技战,理解网络与算力深度融合助力高维度竞争 1:对抗封锁,需 ...

  2. 牛客网PAT练兵场-科学计数法

    题目地址:https://www.nowcoder.com/pat/6/problem/4050 题解:模拟题 /** * Copyright(c) * All rights reserved. * ...

  3. Nuxt.js 踩坑记录,(1)引入fs包报错

    今天又是码农的一天. 但是写着写着,不知道为啥就页面就报错了, 如图所示,我在db/app.js下引入了fs这个模块,提示我npm install,我也照做了,但是仍然报错. 通过各种百度,踩坑,最终 ...

  4. mysql事务级别和spring中应用

    一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...

  5. 什么是谷歌PageRank (简称PR值)

    http://www.wocaoseo.com/thread-213-1-1.html 谷歌pageRank是谷歌用来评测网页质量高低的一个工具,主要分为0到10共11个等级,目前有很多的工具或谷歌工 ...

  6. QString 字符串操作

    Qt QString字符串分割.截取(转载) 在做项目中不可避免的会使用到一串字符串中的一段字符,因此常常需要截取字符串. 有两种方式可以解决这个问题: 方法一:QString分割字符串: QStri ...

  7. Kubernetes Operator基础入门

    本文转自Rancher Labs 你是否曾经想过SRE团队是如何有效地成功管理复杂的应用?在Kubernetes生态系统中,Kubernetes Operator可以给你答案.在本文中,我们将研究Op ...

  8. PJSIP开发指南-第二章

    一.模块 2.1    模块框架 模块框架的主要作用是在应用程序组件之间分发SIP消息,PJSIP的所有的组件,包括dialog和transaction都是以模块方式实现的,没有模块,核心协议栈将不知 ...

  9. vue的computed属性的理解

    computed: { selectedQuestions() { let selectedQuestions = this.editedItem.questions; return this.que ...

  10. Google谷歌在根据流量统计分析当年的2008年汶川大地震

    这是一张2008年的老图,Google当时的博文说道:"当我们依照惯例整理和分析谷歌搜索引擎的流量数据时,一条从未见过的曲线出现在我们面前.当意识到发生了什么事情时,我们的眼睛湿润了.&qu ...