本帖最后由 我爱睡觉 于 2016-1-20 16:32 编辑
原文出处: iceAeterna 6.类实例化
这里需要明白什么是类初始化,什么是类实例化,以及类的实例对象的初始化
如前面所述,类初始化时对类(静态)变量赋予指定的初始值,类初始化之后就可以访问类的静态字段和方法,而访问类的非静态(实例)字段和方法,就需要创建类的对象实例,故类的实例化是在类的初始化之后,是在堆上创建一个该类的对象。
类的静态方法和字段属于类,作为类型数据保存在方法区,其生命周期取决于类,而实例方法和字段位于Java堆,其生命周期取决于对象的生命周期。
类的初始化会从祖先类到子类、按出现顺序,对类变量的初始化语句、静态初始化语句块依次进行初始化。而对类实例的初始化也类似,会从祖先类到子类、按出现顺序,对类成员的初始化语句、实例初始化块、构造方法依次进行初始化。
比如: - package com.ice.init;
- public class Parent {
- public static int i = print("parent static:i");
- public int ii = print("parent:ii");
- static{
- print("父类静态初始化");
- }
- {
- print("父类实例初始化");
- }
- public Parent(String str) {
- System.out.println("parent constructor:" + str);
- }
- public static int print(String str){
- System.out.println("initial:" + str);
- return i;
- }
- }
复制代码
子类Child如下: - package com.ice.init;
- public class Child extends Parent{
- public static int i = print("child static:i");
- public int ii = print("child:ii");
- static{
- print("子类静态初始化");
- }
- {
- print("子类实例初始化");
- }
- public Child(String str) {
- super(str);
- System.out.println("Child constructor:" + str);
- }
- public static int print(String str){
- System.out.println("initial:" + str);
- return i;
- }
- public static void main(String args[]){
- Child child = new Child("cindy");
- }
- }
复制代码
其初始化顺序为:
Java编译器为每个类生成了至少一个实例初始化方法< init >,一个< init >方法分为三部分: 另一个初始化方法< init >(),对任意实例成员的初始化的字节码,构造方法的方法体的字节码
< init >方法的调用如下:
若< init >指明从this()方法明确调用另一个构造方法,那么将调用另一个构造方法,否则,若该类有直接超类,那么,若< init >指明从super()方法明确调用其超类的构造方法,那么将调用超类的构造方法,否则,将默认调用超类的无参构造方法。这样,将从其祖先类到该 类,分别完成对应的实例成员的初始化(可能被子类覆盖)
接下来以一道题结束本节:
判断输出: - package com.ice.init;
- class T implements Cloneable{
- public static int k = 0;
- public static T t1 = new T("t1");
- public static T t2 = new T("t2");
- public static int i = print("i");
- public static int n = 99;
- public int j = print("j");
- {
- print("构造块");
- }
- static {
- print("静态块");
- }
- public T(String str) {
- System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
- ++n; ++ i;
- }
- public static int print(String str){
- System.out.println((++k) +":" + str + " i=" + i + " n=" + n);
- ++n;
- return ++ i;
- }
- public static void main(String[] args){
- T t = new T("init");
- }
- }
复制代码
题解如下:- (1).首先T类被加载、连接后进行初始化,会先对字段k、t1、t2、i、n以及static块进行初始化。
- (2).t1实例的初始化会初始化实例成员j,(实际上先进行父类实例内容的初始化)先调用静态方法print,并执行实例初始化块{},输出:
- 1: j i=0 n= 0(i和n都还没有初始化)
- 2:构造块 i=1 n=1
- (3)随后调用t1实例的构造函数,输出:
- 3:t1 i=2 n=2
- (4).类似有t2实例的初始化:
- 4: j i=3 n= 3
- 5:构造块 i=4 n=4
- 6:t2 i=5 n=5
- (5).i的初始化:
- 7.i i=6 n=6
- (6).n的初始化和静态块的初始化:
- 8.静态块 i=7 n=99(n已经被初始化)
- (7).t实例的初始化:
- 9.j i=8 n= 100
- 10.构造块 i=9 n= 101
- 11.init i=10 n= 102
复制代码
|