为了使用类需要3步工作:
1.加载。这是由类加载器执行的。该步骤将查找字节码,并从这些字节码创建一个Class对象。
2.链接。在链接阶段将验证类的字节码,为静态域分配存储空间,并且如果必需的话,还将解析这个类创建的对其他类的所有引用。
3.初始化。如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。
初始化被延迟到了对静态方法或者非常数静态域进行首次引用时才执行。
看段代码:
import java.util.Random;
class Initable {
static final int staticFinal = 47;
static final int staticFinal2 = ClassInitialization.rand.nextInt(1000);
static {
System.out.println("Initializing Initable");
}
}
class Initable2 {
static int staticNonFinal = 147;
static {
System.out.println("Initializing Initable2");
}
}
class Initable3 {
static int staticNonFinal = 74;
static {
System.out.println("Initializing Initable3");
}
}
public class ClassInitialization {
public static Random rand = new Random(47);
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
Class initable = Initable.class; //使用.class获得Class对象的引用,不会进行初始化
System.out.println("After creating Initable ref"); //打印输出
//staticFinal为编译期常量。不需对Initable类进行初始化就可以读取
System.out.println(Initable.staticFinal);
//staticFinal2不是编译期常量,要获得它需先进行类初始化,因此会先执行static块中的语句,再打印出staticFinal2
System.out.println(Initable.staticFinal2);
//staticNonFinal不是final的,因此在对它访问时,总是要求在它被读取之前,要先进行链接和初始化。所以也会先执行static块中的语句,再打印出staticNonFinal
System.out.println(Initable2.staticNonFinal);
//使用forName方法获得Class引用会进行初始化,因此会先执行static块中的语句
Class initable3 = Class.forName("Initable3");
System.out.println("After creating Initable3");
//直接打印出staticNonFinal
System.out.println(Initable3.staticNonFinal);
}
}
这段代码的执行结果为:
After creating Initable ref
47
Initializing Initable
258
Initializing Initable2
147
Initializing Initable3
After creating Initable3
74
为什么是这样呢?分析见代码注释
分享到:
相关推荐
### 类初始化顺序详解 本文将基于给定的Java示例代码深入探讨类初始化的顺序问题。这不仅是Java语言的关键特性之一,在其他面向对象语言(如C++、.NET)中也有相似的概念。理解这一概念有助于程序员更好地掌握面向...
在Java编程语言中,类和实例的初始化...总之,类初始化和实例初始化是Java程序运行的基础,理解这两个过程有助于编写更高效、更健壮的代码。同时,掌握方法的重写规则和多态性的应用,可以充分利用面向对象编程的优势。
在本教程中,我们将深入探讨"委托"、"匿名方法"、"自动属性"、"集合初始化器"以及"类初始化器"这五个核心概念。 首先,我们来看"委托"。委托在.NET中类似于C++中的函数指针,但更安全,支持类型检查。委托定义了一...
03_JavaSE面试题:类初始化和实例初始化等
首先,了解类初始化的顺序至关重要。当创建一个子类实例时,初始化过程遵循以下步骤: 1. **静态初始化**:首先,执行父类的静态初始化块,然后执行子类的静态初始化块。静态初始化块用于初始化类级别的静态变量,...
在实际编程中,理解类初始化顺序至关重要,因为它可以帮助避免潜在的错误和异常。例如,确保在访问成员变量前它们已被正确初始化,或者在适当的地方初始化静态变量以避免并发问题。遵循良好的编码规范,如将初始化...
类--初始化块"); 39. } 40. // 构造器 41. public SubClass() { 42. System.out.println("子类--构造器"); 43. } 44. 45. public static void main(String[] args) { 46. new SubClass(); 47. } 48.} 当我们运行这段...
Kotlin 1.3 案例集锦第五章 登录渐变动画类初始化
在"commonInitialize.css"中,通常会包含以下几类初始化内容: 1. **重置默认样式**:这一步是为了消除浏览器之间的样式差异,如设置`*{margin:0;padding:0;}`,这将清空所有元素的内外边距,确保元素布局的一致性...
6. **类初始化与类加载器**: - 类的初始化是由对应的类加载器触发的,当且仅当以下条件之一满足时: - 遇到new关键字实例化对象; - 遇到静态字段(非final)并对其进行访问; - 遇到静态方法的调用; - 使用...
使用集合类初始化 VB还提供了集合类,如`ArrayList`或`Generic.List(Of T)`,它们可以更灵活地处理动态数据。虽然这不是标准的数组初始化,但它们在处理可变大小的数据集时非常有用。例如,使用`ArrayList`: ```...
【深入Java虚拟机(三)——类的生命周期(下)类的初始化1】 类的生命周期在Java中是一个关键的概念,它涵盖了从加载到卸载的整个过程。在类的生命周期中,初始化阶段是非常重要的,因为它涉及到类的静态变量的赋值...
// 工具类初始化 AnnotationInjector.init(this); } } ``` 4. **创建工具类** 创建一个工具类,如`AnnotationInjector`,它会遍历目标类的所有字段,查找带有`BindView`注解的成员,并执行初始化操作。这个...
总结起来,C++中的类初始化主要通过构造函数的成员初始化列表进行,它提供了高效、清晰的初始化方式。理解和掌握这一机制对于编写高效、可维护的C++代码至关重要。通过实践和尝试不同的示例,读者可以更好地巩固这一...
本文详细介绍了类继承中的初始化顺序问题,包括初始化的基本概念、初始化过程中的关键步骤以及如何正确处理基类和子类之间的构造函数调用。理解这些概念对于编写高效、可维护的面向对象程序至关重要。希望通过对这些...
- 类初始化:在类初始化阶段,静态属性的内存被分配,然后执行静态初始化块来初始化静态属性。这个过程是自顶向下的,从`java.lang.Object`开始,逐级执行每个类的静态初始化块。 总结起来,Java初始化块是Java中...
Java类初始化和实例化是程序开发中至关重要的环节,它涉及到类加载、静态变量的初始化以及构造器的执行。在Java中,类的初始化通常在以下几个情况发生: 1. 使用`new`关键字创建实例。 2. 访问或修改类的静态字段...
首先,需要了解Java类初始化的基本规则,即在类的静态变量、静态初始化块、变量、初始化块、构造器这五个部分中,它们的初始化顺序依次是:静态变量、静态初始化块、变量、初始化块、构造器。这个顺序在单个类中是...
按照 Java 的规定,以下列出了类初始化的基本顺序: 1. **静态域初始化**:所有静态域按它们在源代码中出现的顺序进行初始化。 2. **静态块执行**:所有静态块按它们在源代码中出现的顺序依次执行。 3. **非静态域...