首先说一下Java如何初始化。
对象的初始化工作必须在对象被调用之前完成。那么在创建对象时就需要调用类的初始化方法,而这个方法就是构造方法。为了确保构造方法名称唯一,即能够为Java编译器识别,在这里就是用于类名完全相同的方法作为构造方法。构造方法允许重载,但没有返回值。
下面就来看一下Java对象初始化的顺序。
在类内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,他们仍然会在任何方法(包括构造方法)调用之前得到初始化。但是存在特殊的情况:静态变量。静态变量会在非静态变量初始前进行初始化,并且静态变量的初始化只有在必要时刻才会进行,且仅初始化一次。
最后看一下Java清理。
在java中有垃圾回收器负责回收无用对象占据的内存资源。但是,gc只能回收那些使用new关键字分贝的内存,对于其他方式的内存分配,gc无能为力。为了应对这种情况,java允许在类中定义finalize()方法。它的工作原理是这样的:一旦gc准备好释放对象的内存空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才真正回收对象占用的内存。但在实际应用中,不能依赖于finalize()完成清理工作,因为它只有在垃圾回收时才会被执行。那什么时候会执行gc呢?不一定了,也可能在程序结束时也没有执行。
那么实际上Java的初始化顺序可以分为以下三个方面:
1. Java的初始化顺序:(静态变量、静态初始化块)>(变量、初始化块)>构造器
来个例子:
public class InitialOrderTest {
private static String staticField = "静态变量";//静态变量
private String field = "变量"; // 变量
static { // 静态初始化块
System.out.println(staticField);
System.out.println("静态初始化块");
}
{// 初始化块
System.out.println(field);
System.out.println("初始化块");
}
InitialOrderTest() { // 构造器
System.out.println("构造器");
}
public static void main(String[] args) {
new InitialOrderTest();
}
}
输出:
静态变量
静态初始化块
变量
初始化块
构造器
2. 对于含有继承的情况会先初始化父类的,再初始化子类的
上例子:
class Parent {
// 静态变量
public static String p_StaticField = "父类--静态变量";
// 变量
public String p_Field = "父类--变量";
// 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
// 初始化块
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}
// 构造器
public Parent() {
System.out.println("父类--构造器");
}
}
public class InitialOrderTest1 extends Parent {
// 静态变量
public static String s_StaticField = "子类--静态变量";
// 变量
public String s_Field = "子类--变量";
// 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}
// 初始化块
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}
// 构造器
public InitialOrderTest1() {
System.out.println("子类--构造器");
}
// 程序入口
public static void main(String[] args) {
new InitialOrderTest1();
}
}
输出:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
注意:并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了
3. 对于静态变量和静态初始化块之间 或者变量和初始化块之间的初始化顺序是取决于它们在类中出现的先后顺序。
无例无真相:
public class InitialOrderTest2 {
// 静态变量
public static TestA a = new TestA();
// 静态初始化块
static {
System.out.println("静态初始化块");
}
// 静态变量
public static TestB b = new TestB();
public static void main(String[] args) {
new InitialOrderTest2();
}
}
class TestA {
public TestA() {
System.out.println("Test--A");
}
}
class TestB {
public TestB() {
System.out.println("Test--B");
}
}
输出:
Test--A
静态初始化块
Test—B
分享到:
相关推荐
作为一名程序员必须知道Java初始化顺序......
Java初始化顺序1
C++和Java初始化顺序的比较代码, 详细的解说请参考博客地址, http://blog.csdn.net/ostrichmyself/archive/2010/11/25/6035538.aspx
介绍一下java程序初始化的顺序,这会对您以后的开发所有帮助
详细讲解java类中静态变量,普通标量,对象、基本类型的初始化顺序。
本篇文章主要介绍了Spring 中如何控制2个bean中的初始化顺序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
一个java代码初始化具体过程的的demo
对java类初始化以及顺序,详解,由于转载仅供大家参考!
具体内容见博客
java面试题-类的初始化顺序.doc 大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,...
详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序
java 静态_非静态 字段_方法_代码块 子类父类构造_初始化顺序! 三个class 让你清清楚楚 第一个class java代码如下: package initialOrder; class Parent { // 静态变量 public static String p_StaticField...
“礼让”原则学习Java对象初始化顺序
java对象的初始化顺序[参考].pdf
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,网上关于Java中对象初始化顺序的文章很多,这篇文章我们将详细介绍Java中对象初始化顺序。有需要的可以参考学习。
JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看
JAVA面试题解惑系列类的初始化顺序JAVA程序员JAVA工程师面试必看.pdf