初始化的顺序是先“静态”,(如果它们尚未因前面的对象创建过程而被初始化),后“非静态”。
具体的创建过程:
1.当首次创建某个类对象的时候,或者该类的静态方法/静态域首次被访问时,Java解释器必须查找该类的路径,以定位该类的class文件。
2.然后载入该class(创建一个Class对象),有关静态初始化的动作都会执行。静态初始化只在Class对象首次加载的时候进行一次。
例如:按照出现顺序执行初始化动作
static int n1 = f(1);
static{
n3 = f(3);
//静态域的初始化语句不必担心非法向前引用,但是如果是访问n3,就会发生非法向前引用的错误
System.out.println("println");
}
static int n2 = f(2);
static int n3;
static int f(int i){
System.out.println("n"+i);
return i;
}
创建对象或者访问此类的某个静态域/静态方法,打印出来:
n1
n3
println
n2
3.当使用new操作符创建对象的时候,首先将在堆上为待创建的对象分配足够的存储空间。
4.这块存储空间会被清零,这就自动的将类中所有基本类型数据设置成了默认值(数值和字符是0,布尔是false),而引用则被设置成了null。
5.按出现顺序执行所有出现于域(非静态域)定义处的初始化动作。
6.执行构造器。
运行一下下面的例子就都清楚了。
public class MembersInitializeSequence {
public static void main(String[] args){
Bowl.f();
System.out.println("实例化一个Bowl对象");
new Bowl();
System.out.println("再实例化一个Bowl对象");
new Bowl();
}
}
class Cup {
Cup(int i){
System.out.println("new Cup("+i+")");
}
}
class Bowl{
Cup c1;
Cup c2 = new Cup(2);
{
c1 = new Cup(1);
}
static{
c4 = new Cup(4);
System.out.println("Bowl中的静态快,静态块只在类加载的时候运行,所以只运行一次");
}
static Cup c3 = new Cup(3);
static Cup c4;
Bowl(){
System.out.println("new Bowl()");
}
static void f(){
System.out.println("Bowl中的静态方法f()被访问");
}
}
在类被继承的情况下,初始化的顺序:
1.初始化子类,类加载器在加载它的时候会发现它继承了另外一个类,类加载器要先把父类加载进来。于是开始加载父类,父类的静态部分被按顺序加载。之后子类的静态部分被加载。这样的顺序是考虑子类的静态域可能会依赖父类的静态域;
2.父类的非静态部分被加载;
3.子类指定的父类的构造器;
4.子类的非静态部分被加载;
5.子类构造器的其余部分。
多个层次的继承关系,顺序也同理。
例如
public class MembersInitializeSequenceEx {
public static void main(String[] args){
// new Cat();
new Tiger();
}
}
class Cat{
int c1 = f1(1);
int f1(int i){
System.out.println("Cat unstatic "+i);
return i;
}
{
System.out.println("Cat unstatic block");
}
static int c2 = f2(2);
static int f2(int i){
System.out.println("Cat static "+i);
return i;
}
static{
System.out.println("Cat static block");
}
public Cat(){
System.out.println("new Cat()");
}
}
class Tiger extends Cat{
int c3 = f1(3);
@Override
int f1(int i){
System.out.println("Tiger unstatic "+i);
return i;
}
{
System.out.println("Tiger unstatic block");
}
static int c4 = f2(4);
static int f2(int i){
System.out.println("Tiger static "+i);
return i;
}
static{
System.out.println("Tiger static block");
}
public Tiger(){
super();
System.out.println("new Tiger()");
}
}
分享到:
相关推荐
Java类成员初始化顺序详解 Java类成员初始化顺序是Java编程中一个非常重要的概念,它直接关系到Java类的实例化和成员变量的初始化顺序。下面我们将通过详细的示例代码来介绍Java类成员初始化顺序。 首先,Java类中...
当我们谈论“Java类继承初始化顺序”时,涉及到的关键知识点包括构造器、成员变量的初始化、super关键字以及方法的覆盖。 首先,了解类初始化的顺序至关重要。当创建一个子类实例时,初始化过程遵循以下步骤: 1. ...
类--初始化块"); 39. } 40. // 构造器 41. public SubClass() { 42. System.out.println("子类--构造器"); 43. } 44. 45. public static void main(String[]...因此,掌握类的初始化顺序是每个Java开发者必备的知识点。
### Java中类的初始化顺序详解 #### 一、概述 在Java编程语言中,类的初始化是一个非常重要的概念。类的初始化涉及到多个方面,包括静态成员变量、实例成员变量、静态初始化块、实例初始化块以及构造函数等。本文...
总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和实例初始化块、构造函数、成员变量初始化以及继承关系的影响。这个demo是学习和理解这些概念的重要工具,通过实际操作可以加深对Java内存管理和对象生命...
本文详细介绍了类继承中的初始化顺序问题,包括初始化的基本概念、初始化过程中的关键步骤以及如何正确处理基类和子类之间的构造函数调用。理解这些概念对于编写高效、可维护的面向对象程序至关重要。希望通过对这些...
详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序
总之,类的初始化顺序是:静态成员 -> 静态初始化块 -> 非静态成员 -> 非静态初始化块 -> 构造器。这个顺序同样适用于继承关系,只是会先初始化父类的部分,再初始化子类的部分。掌握这一知识能帮助程序员更好地设计...
在Java中,类的初始化顺序是面试中的经典问题之一,它涉及到继承、静态成员以及实例成员等多个方面。正确理解类的初始化顺序对于编写正确、高效的代码至关重要。 首先,需要了解Java类初始化的基本规则,即在类的...
在Java编程语言中,初始化块是程序执行时用于初始化对象或类的重要机制。这里我们将深入探讨两种类型的初始化块:静态初始化块(Static Initializer Block)和对象初始化块(Instance Initializer Block)。这两种...
静态变量`a`和`b`的初始化顺序是按照它们在源代码中的出现顺序进行的,这里`a`先被初始化,然后是`b`。 另外,Java程序对类的使用有主动使用和被动使用两种情况。主动使用包括以下六种场景: 1. **创建类的实例**...
Java 初始化顺序详解 在 Java 中,变量可以分为两类:类变量(静态变量)和实例变量(对象变量)。类变量是使用 static 关键字修饰的变量,它们属于类,而不是对象。实例变量则是没有使用 static 关键字修饰的变量...
JAVA面试题解惑系列(一)——类的初始化顺序 JAVA 是一门面向对象的编程语言,类的初始化顺序是 JAVA 程序员和 JAVA 工程师面试中一个非常重要的知识点。本文将详细讲解类的初始化顺序,并提供了相关的测试代码,...
Java对象的初始化顺序是一个关键的编程概念,它涉及到类加载、静态初始化、实例初始化等多个步骤。下面我们将详细探讨这些步骤。 首先,当程序运行并创建一个新的对象时,JVM(Java虚拟机)会按照特定的顺序来初始...
总结来说,对于Java程序员和工程师而言,了解类的初始化顺序不仅是面试中常问的问题,也是日常编程中必须掌握的基础知识。这一知识的掌握,能够帮助开发者更好地管理内存、避免初始化时的错误和数据竞争等问题,从而...
##### 步骤一:成员初始化顺序 成员变量的初始化顺序遵循以下规则: 1. **实例变量的初始化**:按照它们在类中出现的顺序进行初始化。 2. **构造函数中的初始化**:在构造函数内部,可以显式初始化成员变量,这...
1. 父类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行) 2. 父类构造函数 3. 子类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行) 4. 子类构造方法 在实例化过程中,JVM将按照代码...
Java 变量初始化的时机可以分为两类:实例变量初始化和类变量初始化。 实例变量初始化 实例变量初始化可以在三个地方进行: 1. 定义实例变量的时候指定初始值; 2. 非静态初始化代码块中对实例变量指定初值; 3. ...
本篇文章将深入探讨C++和Java中变量和成员初始化的差异,并通过具体的代码示例进行对比。 在C++中,初始化顺序遵循以下规则: 1. 静态成员变量:无论它们在哪里定义,静态成员变量都按照声明的顺序初始化。 2. 非...
程序通过一系列输出语句来展示类成员变量、静态成员变量以及构造函数的初始化顺序。下面将逐一分析这些步骤,并解释为何会按照这样的顺序进行。 ### 初始化顺序解析 #### 静态成员变量与静态初始化块 1. **父类...