java对象的初始化顺序
来源:互联网 发布:is网络兼职是真的吗 编辑:程序博客网 时间:2024/06/06 01:29
java对象的初始化顺序
来源:http://wenku.baidu.com/view/2631ba717fd5360cba1adb95.html
对象初始化流程:
我们根据一段代码来分析对象初始化流程:
/**
*基类包含一静态变量、包含一实例变量
*包含一个静态初始化块以及一个构造子
*/
class Base{
public static int a = 10;
public int b = 20;
static
{
System.out.println("Static Init Base " + a);
//System.out.println("Null Init " + b);
}
public Base()
{
System.out.println("Init Base " + this.b);
}
}
/**
*一级子类和基类包含的内容一样
**/
class SuperClass extends Base{
public static int a1 = getSuperStaticNumber();
public int b1 = getSuperInstanceNumber();
public SuperClass()
{
System.out.println("Init SuperClass" + this.b1);
}
static
{
System.out.println("Static Init SuperClass" + a1);
}
public static int getSuperStaticNumber()
{
System.out.println("Static member init");
return 100;
}
public int getSuperInstanceNumber()
{
System.out.println("Instance member init");
return 200;
}
}
/**
*二级子类为测试该代码的驱动类
*/
public class SubClass extends SuperClass{
public static int a2 = getStaticNumber();
public int b2 = getInstanceNumber();
public SubClass()
{
System.out.println("Init SubClass " + this.b2);
}
public static int getStaticNumber()
{
System.out.println("Static member init Sub");
return 1000;
}
public int getInstanceNumber()
{
System.out.println("Instance member init Sub");
return 2000;
}
public static void main(String args[])
{
new SubClass();
}
static
{
System.out.println("Static Init " + a2);
}
}
这段代码会有以下输出:
Static Init Base 10
Static member init
Static Init SuperClass 100
Static member init Sub
Static Init 1000
Init Base 20
Instance member init
Init SuperClass 200
Instance member init Sub
Init SubClass 2000
[1]对象在初始化过程,JVM会先去搜索该类的顶级父类,直到搜索到我们所定义的SubClass继承树上直接继承于Object类的子类,在这里就是Base类;
[2]然后JVM会先加载Base类,然后初始化Base类的静态变量a,然后执行Base类的静态初始化块,按照这样第一句话会输出:Static Init Base 10【*:此时该类还未调用构造函数,构造函数是实例化的时候调用的】
[3]然后JVM按照继承树往下搜索,继续加载Base类的子类,按照静态成员函数->静态成员变量->静态初始化块的顺序往下递归,直到加载完我们使用的对象所在的类。
[4]类加载完了过后开始对类进行实例化操作,这个过程还是会先搜索到直接继承于Object类的子类,在这里就是Base类;
[5]JVM会实例化Base类的成员函数,然后实例化成员变量,最后调用Base类的构造函数;
[6]之后,JVM会递归往继承树下边进行调用,顺序还是遵循:成员函数->成员变量->构造函数;
[7]最后直到SubClass类的构造函数调用完成
按照上边书写的逻辑,我们就很清楚了上边源代码的执行结果,而整个JVM初始化某个类的流程就是按照以上逻辑进行
在构造函数调用过程,有几点是需要我们留意的,这里就不提供代码实例,有兴趣的朋友可以自己去试试
[1]如果一个类的父类没有无参数构造函数,也就是说父类自定义了一个带参数的构造函数,那么系统不会提供无参数构造函数,此时子类在调用构造函数的时候必须最开始显示调用super(param),因为在构造函数调用之前系统总会先去调用父类的构造函数
[2]若一个类定义的时候没有提供构造函数,JVM会自动为该类定义一个无参数的构造函数
[3]一个类在调用构造函数的时候,JVM隐藏了一句代码super(),前提是父类未定义构造函数或者显示定义了无参构造函数;其含义就是调用父类的构造函数,如果父类的无参数构造函数被覆盖的话需要在子类构造函数中显示调用父类带参数的构造函数
[4]当类中的成员函数遇到变量的时候,会先根据变量名在函数域即局部变量范围内去寻找该变量,如果找不到才会去寻找实例变量或者静态变量,其意思可以理解为局部变量可以和实例变量或者静态变量同名,而且会在函数调用过程优先使用,这个原因在于在函数范围内,如果调用的变量是实例变量,其中前缀this.被隐藏了。
- java对象的初始化顺序
- java对象的初始化顺序
- java对象的初始化顺序
- JAVA对象的初始化顺序
- java对象的初始化顺序
- java对象初始化的顺序
- java对象的初始化顺序
- java 对象的初始化顺序
- JAVA对象初始化顺序
- java对象初始化顺序
- Java 对象初始化顺序
- Java对象初始化顺序
- Java对象初始化顺序
- Java 对象初始化顺序
- Java 对象初始化顺序
- Java对象初始化顺序
- java对象初始化顺序
- java对象初始化顺序
- 多线程Thread与后台线程setDaemon,使用Runnable接口创建多线程
- 深入掌握JMS(十一):TemporaryQueue和TemporaryTopic
- NCalc - Mathematical Expressions Evaluator for .NET
- connect pc-mobile-tv 让所有的设备互联
- WinCE内存映射文件技术
- java对象的初始化顺序
- 给MSSQL查询结果追加行号
- 实现在一个字符串中删除中文字符及空格的实现代码
- How to work hard easily!
- C/C++语言可变参数表深层探索
- framebuffer下用libjeg库显示jpeg图片
- 虚拟内存、CreateFileMapping使用及在WINCE失败的原因
- 纵向无缝隙滚动显示JS控制代码
- Linux文件查找命令find,xargs详述