A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 我爱睡觉 于 2016-1-20 16:32 编辑

原文出处: iceAeterna
6.类实例化
这里需要明白什么是类初始化,什么是类实例化,以及类的实例对象的初始化
如前面所述,类初始化时对类(静态)变量赋予指定的初始值,类初始化之后就可以访问类的静态字段和方法,而访问类的非静态(实例)字段和方法,就需要创建类的对象实例,故类的实例化是在类的初始化之后,是在堆上创建一个该类的对象。
类的静态方法和字段属于类,作为类型数据保存在方法区,其生命周期取决于类,而实例方法和字段位于Java堆,其生命周期取决于对象的生命周期。
  类的初始化会从祖先类到子类、按出现顺序,对类变量的初始化语句、静态初始化语句块依次进行初始化。而对类实例的初始化也类似,会从祖先类到子类、按出现顺序,对类成员的初始化语句、实例初始化块、构造方法依次进行初始化。
比如:
  1. package com.ice.init;

  2. public class Parent {
  3.     public static int i = print("parent static:i");
  4.     public int ii = print("parent:ii");

  5.     static{
  6.         print("父类静态初始化");
  7.     }

  8.     {
  9.         print("父类实例初始化");
  10.     }

  11.     public Parent(String str) {
  12.         System.out.println("parent constructor:" + str);
  13.     }

  14.     public static int print(String str){
  15.         System.out.println("initial:" + str);
  16.         return i;
  17.     }
  18. }
复制代码



子类Child如下:
  1. package com.ice.init;

  2. public class Child extends Parent{
  3.     public static int i = print("child static:i");
  4.     public int ii = print("child:ii");

  5.     static{
  6.         print("子类静态初始化");
  7.     }

  8.     {
  9.         print("子类实例初始化");
  10.     }

  11.     public Child(String str) {
  12.         super(str);
  13.         System.out.println("Child constructor:" + str);
  14.     }

  15.     public static int print(String str){
  16.         System.out.println("initial:" + str);
  17.         return i;
  18.     }

  19.     public static void main(String args[]){
  20.         Child child = new Child("cindy");
  21.     }
  22. }
复制代码



其初始化顺序为:

Java编译器为每个类生成了至少一个实例初始化方法< init >,一个< init >方法分为三部分: 另一个初始化方法< init >(),对任意实例成员的初始化的字节码,构造方法的方法体的字节码
< init >方法的调用如下:
若< init >指明从this()方法明确调用另一个构造方法,那么将调用另一个构造方法,否则,若该类有直接超类,那么,若< init >指明从super()方法明确调用其超类的构造方法,那么将调用超类的构造方法,否则,将默认调用超类的无参构造方法。这样,将从其祖先类到该 类,分别完成对应的实例成员的初始化(可能被子类覆盖)
接下来以一道题结束本节:
判断输出:
  1. package com.ice.init;

  2. class T  implements Cloneable{
  3.       public static int k = 0;
  4.       public static T t1 = new T("t1");
  5.       public static T t2 = new T("t2");
  6.       public static int i = print("i");
  7.       public static int n = 99;

  8.       public int j = print("j");
  9.       {
  10.           print("构造块");
  11.       }

  12.       static {
  13.           print("静态块");
  14.       }

  15.       public T(String str) {
  16.           System.out.println((++k) + ":" + str + "    i=" + i + "  n=" + n);
  17.           ++n; ++ i;
  18.       }

  19.       public static int print(String str){
  20.           System.out.println((++k) +":" + str + "   i=" + i + "   n=" + n);
  21.           ++n;
  22.           return ++ i;
  23.       }

  24.       public static void main(String[] args){
  25.           T t = new T("init");
  26.       }
  27.     }
复制代码




题解如下:
  1. (1).首先T类被加载、连接后进行初始化,会先对字段k、t1、t2、i、n以及static块进行初始化。
  2. (2).t1实例的初始化会初始化实例成员j,(实际上先进行父类实例内容的初始化)先调用静态方法print,并执行实例初始化块{},输出:
  3.  1: j i=0 n= 0(i和n都还没有初始化)
  4.  2:构造块 i=1 n=1
  5. (3)随后调用t1实例的构造函数,输出:
  6.  3:t1 i=2 n=2
  7. (4).类似有t2实例的初始化:
  8.  4: j i=3 n= 3
  9.  5:构造块 i=4 n=4
  10.  6:t2 i=5 n=5
  11. (5).i的初始化:
  12.  7.i i=6 n=6
  13. (6).n的初始化和静态块的初始化:
  14.  8.静态块 i=7 n=99(n已经被初始化)
  15. (7).t实例的初始化:
  16.  9.j i=8 n= 100
  17.  10.构造块 i=9 n= 101
  18.  11.init i=10 n= 102
复制代码







0 个回复

您需要登录后才可以回帖 登录 | 加入黑马