在讲类的初始化的流程前,我们最好是能够先了解下java虚拟机的体系结构
java虚拟机内部体系结构(本图引自深入java虚拟机第二版)
首先,对上图中的几个区域,作个简单的介绍
一,类装载子系统:
我们都知道,java文件编译后生成的是一个class文件的字节码,而在系统运行时,要用到某个类时,java虚拟机将class文件
加载入系统,然后做一系列的工作,而加载的任务就是由类装载器子系统完成。
java虚拟机中有两种类装载器:启动类装载器和用户自定义类装载器,类的装载过程,不是这里的重点,所以,不作具体的描述。
二,运行时数据区
《深入java虚拟机》写道
当java虚拟机运行一个程序时,它需要内存来存储许多的东西,例如,字节码,从已装载class文件中得到的其他信息,程序创建的对象,
传递给方法的参数,返回值,局部变量,以及运算的中间结果等等。java虚拟机把这些东西都组织到几个“运行时数据区”中,便于管理
1,方法区
当虚拟机装载一个class文件后,java虚拟机将解析的类信息存在到方法区中,
2,堆
当程序运行时,虚拟机将所有程序在运行时创建的对象放入堆中
3,java栈
存储线程中java方法的调用状态,包括局部变量,调用的参数和返回值
4,pc寄存器
当每一格新线程被创建时,他都有一个自己的pc寄存器
5,本地方法栈
用于在调用本地方法时使用的的栈
从上面几点说明中,我们可以放心,方法区和堆是由java虚拟机实例所有线程共享的,而栈和pc寄存器是为单个线程所共享的
三,对象的构建与初始化流程
从上图我们可以看出,对象的构建与初始化主要有两部分组成,即类的准备工作,对象的构建与初始化
1,类的准备工作
我们知道,java中使用到一个类的方式有很多,例如创建一个对象(new A),使用类字面常量(A.Class),调用类的静态变量(A.a),
调用类的静态方法(A.f()),使用Class.forName("A"),那么在这几种情况下,什么时候才会导致出现类准备工作呢,以及执行哪类准备工作中的哪几步呢?
a,其实上在java中除了使用类字面常量(A.Class)以及访问类中“编译常量”时,只运行到类的装载荷类文件验证,
而不进行类变量的初始化外,其他的都会运行整个类准备工作
b,对于类“编译常量”,在分配内存时,会自动将其默认值设置为常量值
c,类变量的初始化和类静态语句块的执行,是按照其编写的顺序来执行的
d,对于继承类,先完成父类的类初始化流程再是子类的初始化流程
c,类的准备工作,只会在执行一次。
按照上面的几点说明, 我们可以看以下代码运行的结果
public class ParentClass {
public static int a=10;
public static int b=initb();
static {
System.out.println("execute para static black..");
}
public static final int c=11;
public ParentClass(){
System.out.println("init ParentClass ");
}
public static int initb(){
System.out.println("execute parent initb..");
return 10;
}
public static void f3(){
System.out.println("execute parent f3");
}
}
使用junit测试
public void testInit(){
System.out.println("ParentClass c is :" +ParentClass.c);
System.out.println("ParentClass a is :" +ParentClass.a);
System.out.println("ParentClass b is :" +ParentClass.b);
}
输出结果如下:
ParentClass c is :11
execute parent initb..
execute para static black..
ParentClass a is :10
ParentClass b is :10
从结果中我们可以看出,由于静态成员域是c是一个“编译常量”所以在给类对象分配内存设置默认值时,c的默认就是 11 ,而不用等到初始化,
因此, 第一句输出时类还没进行初始化的过程,但在调用ParentClass.a时,由于a不时“编译常量”,所以要先进行类的初始化。
如果我们将测试换成
public void testInit(){
System.out.println("ParentClass c is :" +ParentClass.c);
}
输出结果为:
ParentClass c is :11
我们可以看到,访问类的“编译常量”时,是不进行类的变量的初始话的。
而如果用
public void testInit(){
System.out.println("ParentClass a is :" +ParentClass.a);
}
输出为:
execute parent initb..
execute para static black..
ParentClass a is :10
2,对象的创建以及初始化
如图所示,对象的创建流程 是1,给对象分配空间并设置默认值-〉2,初始化变量及执行非静态域-〉3,执行构造函数-〉4,返回对象的引用
我们先从一个例子中来看对象的构建及初始化
public class TestClass {
public int a=10;
{
System.out.println("execute black...");
}
public int b=initb();
public int initb(){
System.out.println("execute testClass init...");
return 110;
}
public TestClass(){
System.out.println("execute TestClass init...");
}
}
测试结果:
new TestClass();
//输出
execute black...
execute testClass init...
execute TestClass init...
从上面的输出, 我们可以反映出,对象成员域的初始话是在构造函数之前执行的。
3,关于继承类对象的构建与初始化
a,前面我们指出类变量的初始化,永远在对象变量及对象的的构造之前完成。而对继承的类的类变量,是先执行类父类变量的初始化
b,对于对象的的构建及初始化流程为
先执行父类成员的初始化,再是父类的构造函数
再执行之类的子类的成员域的初始化,再试子类的构造函数
具体流程如下:
分享到:
相关推荐
- 类加载机制:探讨类加载器的双亲委派模型,理解加载、验证、准备、解析和初始化五个阶段。 - 垃圾回收:研究不同垃圾收集器的工作原理,如Serial、Parallel、CMS、G1等。 - 内存区域:分析堆、栈、方法区、程序...
### Java基础上机题知识点解析 #### 一、类和对象基础题 本部分涉及了类的设计与实现,以及如何通过实例化对象来调用类的方法。主要包括以下几方面: ##### 1. 类的设计与实现 - **Lader 类**: - 属性:上底 ...
3. **类加载机制**:加载、验证、准备、解析、初始化五个阶段,确保类的正确性。 4. **性能优化**:关注JVM参数调整,如-Xms、-Xmx设置堆大小,-XX:NewRatio调整新生代与老年代比例,-XX:SurvivorRatio控制Eden和...
### JAVA SE基础篇-资料整理 #### JAVA历史特点、开发环境 Java 作为一种跨平台的高级编程语言,自1995年由Sun Microsystems公司推出以来,迅速成为了软件开发领域的重要工具之一。Java 最初的设计目的是为了实现...
### Java私塾面试题知识点详解 #### 1. Heap与Stack的区别 Heap和Stack是Java内存管理中的...以上是根据Java私塾面试题整理的知识点详解,涵盖了Java基础中的重要概念和技术细节,对于深入理解Java编程具有重要意义。
这份"Java十大基础笔记整理(PDF)"提供了全面的Java基础知识概览,适合初学者进行学习和复习。下面,我们将深入探讨Java的基础知识,涵盖核心概念、语法和编程实践。 1. **Java简介**:Java是由Sun Microsystems...
除此之外,Spring Boot是近年来非常流行的微服务开发框架,它默认配置了许多常见的Spring应用设置,减少了大量初始化工作。Spring Cloud则为Spring Boot应用提供了分布式系统工具,如服务发现、负载均衡、配置中心等...
构造器用于初始化新创建的对象,代码块可以是实例初始化块或静态初始化块,内部类可以是成员内部类、局部内部类、匿名内部类等。 【封装、继承和多态】 封装是将数据和操作数据的方法绑定在一起,保护数据不被随意...
- 初始化阶段:执行类的初始化过程,设置静态变量初始值,执行静态初始化块。 #### 二十二、char类型与中文字符 - `char`类型可以存储一个中文字符,因为它实际上存储的是Unicode码点。Java使用UTF-16编码,一个`...
毕向东和方立勋是知名的Java技术教育者,他们分别在Java基础和Java Web方面拥有深入的研究,并将这些知识整理成为教程和笔记。以下是从提供的文件内容中挖掘出的Java基础知识和Java Web的知识点。 首先,Java基础...
- **类初始化方法**:构建对象时域的初始化遵循特定顺序。 以上是根据给定文件内容整理出的关键知识点,这些知识点不仅有助于初学者理解Java的基础概念和技术栈,也能为进阶学习提供方向和参考。
### Java基础总结——核心知识点详解 #### 一、Java概述 - **起源与发展**:Java 语言最初由 Sun 公司的 James Gosling 等人在 1991 年开发,当时命名为 Oak,目的是为了控制有线电视交换盒和个人数字助理(PDA)等...
### Java基础知识点整理 #### 第一章 搭建开发环境 **1.1 配置Java环境** 在配置Java开发环境之前,首先需要下载并安装JDK(Java Development Kit)。JDK是Java语言的核心组件,包含了Java运行时环境(JRE)及编译...
Java基础是编程学习的重要部分,尤其对于初学者来说,掌握好Java基础知识至关重要。思维导图是一种有效的学习工具,它能帮助我们系统地整理知识结构,加深理解和记忆。在这个"思维导图-Java基础"中,我们可以预期...
### Java基础知识精炼 #### 一、Java概述与发展历程 Java是一种高级编程语言,由Sun Microsystems公司的James Gosling等人于1991年开始研发,原名为Oak,旨在控制嵌入式设备如有线电视交换盒和PDA。1994年正式更名...
初始化执行类的初始化方法()。 3. **垃圾收集(GC)**: GC是Java的一大优势,它自动管理内存,避免了内存泄漏。常见的GC策略有标记-清除、复制、标记-整理和分代收集。JVM根据对象生命周期的不同,将堆划分为...
- **声明与初始化**:声明变量时需要指定其类型,例如 `int num;` 表示声明了一个整型变量 `num`;初始化则为变量赋初值,例如 `int num = 10;`。 #### 2. 语句 - **控制语句**:包括条件语句 (`if`, `switch`) 和...
### Java基础知识整理 #### 一、面向过程 **1. 搭建Java开发和运行环境** - **JVM (Java Virtual Machine)**: Java虚拟机是执行Java字节码的虚拟机,它提供了运行Java程序所需的运行时环境。 - **JRE (Java ...
### Java学习笔记——Java基础知识整理 #### 一、Java技术入门 Java是一种广泛使用的编程语言,因其跨平台性、安全性和高效性而受到青睐。Java最初由Sun Microsystems开发,并于1995年首次发布。 ##### 1. Sun ...