[后续] Java 中类的实例化过程之多态篇--(终于发现Java 原来是这样则的玩的)
这篇博文依然和大家分享Java 类的实例化过程 值多态篇。和往常一样,直接来上这这阿里的道面试题:
父类的声明如下所示:
1 public class ParentD { 2 //1、类变量进行初始化 3 public static int i = print("parent initialize : i",1); 4 5 public int ii = print("parent", 2); 6 7 public ParentD(String str) { 8 System.out.println("parent construct:"+str); 9 } 10 //2、静态代码块 11 static{ 12 print("父类 静态初始化...",1); 13 } 14 15 /**
*实例初始化块。 3、这一段会在类的实例化过程中被调用,并且是在构造函数执行完之后进行调用,写了这么多年,还是第一次见这么写代码的风格,暂时还不知道他的应用场景,看到的兄弟麻烦请留言喔。
*/
16 { 17 print("父类实例 初始化..",1); 18 } 19 20 public static int print(String str,int i){ 21 System.out.println("initial :"+str); 22 return i; 23 } 24 }
子类的声明如下:
1 public class ChildD extends ParentD{ 2 3 public static int i = print("child d.....", 1);//1、类变量的初始化语句 4 5 public int ii = print("child d...", 2);// 类成员的初始化语句 6 7 static{//2、静态初始化语句块 8 System.out.println("子类静态初始化.."); 9 } 10 11 { 12 print("子类实例初始化", 2); 13 } 14 15 public ChildD(String str) { 16 super(str); 17 System.out.println("child d construct."+str); 18 } 19 20 public static int print(String str,int i){ 21 System.out.println("initial : "+str); 22 23 return i ; 24 } 25 26 public static void main(String[] args) { 27 new ChildD("pbting"); 28 } 29 }
看清楚哦,他们的继承关系 和类中的代码结构。是有那么一点绕。
【知识点-1】类的初始化:在我们日常编程中或者经常看上古时期的代码时会时不时看到这样子的语句:Person.FIMAL。那么在这句调用之前就是所要必经的一步就是 类的初始化。
那么类的初始化主要完成哪些工作呢?【注意看,别眨眼了】类初始化时对类(静态)变量赋予指定的初始值或者执行静态代码块。
【知识点-2】类的初始化顺序:类的初始化会从祖先类到子类,按出现顺序,对类变量的初始化语句,静态初始化语句块依次进行初始化
【知识点-3】(我们往往会看到 好多像似废话的东西,确往往决定最后胜利的关键):类的初始化要先于类的实例初始化
好了看到这里,就基本上能够对上面的那几段代码说出预先打印出那几行了:(马上调到上面,先别看下面的答案,看看是不是和自己想的一样)
initial :parent initialize : i
initial :父类 静态初始化...
initial : child d.....
子类静态初始化..
至此,关于类的初始化中 类的静态变量赋予指定的初始值 并且静态代码块都执行完成,接下来就可以 顺利的进行 【类的实例初始化】
【知识点-4】类的实例初始化。类的实例初始化会从祖先类到子类,按出现的顺序,对类成员的初始化语句,实例初始化块,构造方法依次进行初始化
接下来程序的输出又回到上一篇中了。【注意:让构造函数回归到原生的状态,别让这个代码遮住了你的慧眼】从父类构造方法开始,依次执行类成员初始化语句 ii,这个时候就会调用父类的print 静态方法(想想这里为什么不是调用子类的print 方法,欢迎各位与小编互动哦),这个时候输出:initial :parent。
然后在扫面父类中是否有实例初始化语句块,在该例子中是有的。因此在类成员的初始化语句后执行的实例化语句块,这个时候输出的就是:父类 静态初始化...,再次就是执行构造方法中的语句了。这个时候parent construct:pbting 这句语句就闪亮登场了(等了好久才出场的喔,不容易)。父类的实例初始化完成,接下类就是子类了。子类的顺序和父类的完全一样。因此这个过程的输出如下:
initial :parent initialize : i
initial :父类 静态初始化...
initial : child d.....
子类静态初始化..
initial :parent
initial :父类实例 初始化..
parent construct:pbting
initial : child d...
initial : 子类实例初始化
child d construct.pbting
【恭喜你 如果能够正确输出这些,你完全可以和面试官 谈10K 的月薪了。但是别只会这一点喔,就只练会了这一招。哈哈...】
接下来:看看下面这个代码的程序输出,可以稍微仔细看一下,不然的话 会以为和上面的一样喔。请看题如下:
1 package pbting.com.lucene; 2 3 public class ParentD { 4 5 public static int i = print("parent initialize : i",1); 6 7 public int ii = print("parent"); 8 9 public ParentD(String str) { 10 System.out.println("parent construct:"+str); 11 } 12 13 static{ 14 print("父类 静态初始化...",1); 15 } 16 17 //这一段会在类的实例化过程中被调用,并且是在构造函数执行完之后进行调用 18 { 19 print("父类实例 初始化..",1); 20 } 21 22 public static int print(String str,int i){ 23 System.out.println("initial :"+str); 24 return i; 25 } 26 27 public int print(String str){ 28 System.out.println("parent d 非静态 initial :"+str); 29 return 0 ; 30 } 31 }
1 package pbting.com.lucene; 2 3 public class ChildD extends ParentD{ 4 5 public static int i = print("child d.....", 1); 6 7 public int ii = print("child d..."); 8 9 static{ 10 System.out.println("【深圳市华傲数据技术】-static-子类-静态初始化.."); 11 } 12 13 { 14 print("【深圳市华傲数据技术】-子类实例初始化", 2); 15 } 16 17 public ChildD(String str) { 18 super(str); 19 System.out.println("child d construct."+str); 20 } 21 22 public static int print(String str,int i){ 23 System.out.println("initial : "+str); 24 return i ; 25 } 26 27 public int print(String str){ 28 System.out.println("child d 非静态 initial :"+str); 29 return 0 ; 30 } 31 32 public static void main(String[] args) { 33 new ChildD("pbting"); 34 } 35 }
结果:
initial :parent initialize : i initial :【深圳市华傲数据技术】static-父类 静态初始化... initial : child d..... 【深圳市华傲数据技术】-static-子类-静态初始化.. child d 非静态 initial :parent initial :【深圳市华傲数据技术】-父类-实例 初始化.. parent construct:pbting child d 非静态 initial :child d... initial : 【深圳市华傲数据技术】-子类实例初始化 child d construct.pbting
浙公网安备 33010602011771号