为了使用类需要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
为什么是这样呢?分析见代码注释
分享到:
相关推荐
delegate 委托 匿名方法 自动属性 集合初始化器 类初始化器 委托方法
03_JavaSE面试题:类初始化和实例初始化等
Kotlin 1.3 案例集锦第五章 登录渐变动画类初始化
类的初始化顺序,适用于任何一种面向对象的语言。真正了解面向对象的程序的流程。配有实例
实例初始化过程:实例初始化就是执行()方法:()方法可能重载有多个,有几个构造器就有几个方法()方法由非静态实例
对java类初始化以及顺序,详解,由于转载仅供大家参考!
类继承的初始化顺序类继承的初始化顺序类继承的初始化顺序类继承的初始化顺序
所有构造方法执行顺序如下: 执行父类的构造方法。没有继承默认继承的Object。... // 单独一行的初始化算一个代码块,这个是初始化a的代码块 private String a = "hello"; // 这个只是声明变量,并b不算代码块
Java 的初始化问题和其他高级语言类似。一个明显不一样的地方是体现在它的类加 载过程。传统的编程语言包括C++等,...Sun 公司说类初始化的时机是“initialize on first actice use”, (在首次主动使用时初始 化)。
注意:本文所说的全局变量指的是 variables with static storage,措词来自 c++ 的语言标准文档。 什么时候初始化 ... static initialization: 静态初始化指的是用常量来对变量进行初始化,主要包括 zero init
ButterKnife的demo实现,注解清晰,实现控件初始化,事件注入
C语言的各种初始化(基础类)C语言的各种初始化(基础类)C语言的各种初始化(基础类)C语言的各种初始化(基础类)
主要介绍了Java类初始化和实例化中的2个“雷区”,大家要注意,感兴趣的小伙伴们可以参考一下
当我们一个系统既需要mysql驱动,也需要oracle驱动的时候,在并发加载初始化这些驱动类的过程中产生死锁的可能性非常大,下面是一个模拟的例子,对于Thread2的实现其实是jdk里java.sql.DriverService的逻辑,也是...
java 数组初始化 详解 doc
Revit外部工具无法初始化附加模块的解决方法 大家在安装完Revit或者卸载后重装Revit时是否遇到外部工具无法初始化附加模块的问题,每次打开不停的弹出对话框,烦得要死。 无法初始化附加模块“CollaborateDB”,...
编程思想的第十四章,代码,本人亲测通过后才上传的 这段是介绍编程思想14章构造函数初始化表达式表
摘要视图订阅曹胜欢欢迎关注微信账号:java那些事:csh624366188.每天一篇java相关的文章登录 | 注册学习专区(140)Java程序员从笨鸟到菜
详细讲解java类中静态变量,普通标量,对象、基本类型的初始化顺序。