成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

何時創建Java對象實例

開發 后端
類名可以作為變量的類型來使用,如果一個變量的類型是某個類,那么它將指向這個類的實例,稱為對象實例。所有對象實例和它們的類型都是相容的。本文主要講解Java中對象實例是什么時候被創建的。

Java對象實例何時被創建,這個問題也許你用一句話就能回答完了。但是它的潛在陷阱卻常常被人忽視,這個問題也許并不像你想的那么簡單,不信請你耐心看下去。

我前幾天問一個同學,是不是在調用構造函數后,對象才被實例化?他不假思索的回答說是。

請看下面代碼:

  1. Date date=new Date();  
  2. em.out.println(date.getTime()); 

新手在剛接觸構造函數這個概念的時候。他們常常得出這樣的結論:對象實例是在調用構造函數后創建的。因為調用構造函數后,調用引用(date)的實例方法便不會報NullPointerException的錯誤了。

一、經驗者的觀點

然而,稍稍有經驗的Java程序員便會發現上面的解釋并不正確。這點從構造函數中我們可以調用this關鍵字可以看出。

請看下面代碼:

  1. public class Test  
  2. {  
  3. public Test()  
  4. {  
  5. this.DoSomething();  
  6. }  
  7. private void DoSomething()  
  8. {  
  9. System.out.println("do init");  
  10. }  
  11. }  

這段代碼中我們在構造函數中已經可以操作對象實例。這也就證明了構造函數其實只是用于初始化,早在進入構造函數之前。對象實例便已經被創建了。

二、父類構造函數

當創建一個有父類的子類的時候。對象的實例又是何時被創建的呢?我們也許接觸過下面經典的代碼: 

  1. public class BaseClass  
  2. {  
  3. public BaseClass()  
  4. {  
  5. System.out.println("create base");  
  6. }  
  7. }  
  8. public class SubClass  
  9. {  
  10. public SubClass()  
  11. {  
  12. System.out.println("create sub");  
  13. }  
  14. public static void main(String[] args)  
  15. {  
  16. new SubClass();  
  17. }  

結果是先輸出create base,后輸出create sub。這個結果看起來和現實世界完全一致,先有老爸,再有兒子。因此我相信有很多程序員跟我一樣會認為new SubClass()的過程是:實例化BaseClass->調用BaseClass構造函數初始化->實例化SubClass->調用SubClass構造函數初始化。然而非常不幸的是,這是個錯誤的觀點。

三、奇怪的代碼

以下代碼是為了駁斥上面提到的錯誤觀點。但是這種代碼其實在工作中甚少出現。 

  1. public class BaseClass  
  2.  
  3. {  
  4.  
  5. public BaseClass()  
  6.  
  7. {  
  8.  
  9. System.out.println("create base");  
  10.  
  11. init();  
  12.  
  13. }  
  14.  
  15. protected void init()  
  16. {  
  17. System.out.println("do init");  
  18. }  
  19. }  
  20. public class SubClass  
  21. {  
  22. public SubClass()  
  23. {  
  24. System.out.println("create sub");  
  25. }  
  26. @Override 
  27. protected void init()  
  28. {  
  29. assert this!=null;  
  30. System.out.println("now the working class is:"+this.getClass().getSimpleName());  
  31. System.out.println("in SubClass");  
  32. }  
  33. public static void main(String[] args)  
  34. {  
  35. new SubClass();  
  36. }  

這段代碼運行的結果是先調用父類的構造函數,再調用子類的init()方法,再調用子類的構造函數。

這是一段奇妙的代碼,子類的構造函數居然不是子類第一個被執行的方法。我們早已習慣于通過super方便的調用父類的方法,但是好像從沒這樣嘗試從父類調用子類的方法。

再次聲明,這只是個示例。是為了與您一起探討對象實例化的秘密。通過這個示例,我們再次印證了開頭的觀點:早在構造函數被調用之前,實例便已被創造。若該對象有父類,則早在父類的構造函數被調用之前,實例也已被創造。這讓java顯得有些不面向對象,原來老子兒子其實是一塊兒出生的。

四、奇怪但危險的代碼

本篇是對上篇奇怪代碼的延續。但是這段代碼更加具有疑惑性,理解不當將會讓你出現致命失誤。

請看下面代碼:

  1. public class BaseClass {  
  2. public BaseClass()  
  3. {  
  4. System.out.println("create base");  
  5. init();  
  6. }  
  7. protected void init() {  
  8. System.out.println("in base init");  
  9. }  
  10. }  
  11. public class SubClass extends BaseClass{  
  12. int i=1024;  
  13. String s="13 leaf";  
  14. public SubClass()  
  15. {  
  16. System.out.println("create sub");  
  17. init();  
  18. }  
  19. @Override 
  20. protected void init() {  
  21. assert this!=null;  
  22. System.out.println("now the working class is:"+this.getClass().getSimpleName());  
  23. System.out.println("in SubClass");  
  24. /////////////great line/////////////////  
  25. System.out.println(i);  
  26. System.out.println(s);  
  27. }  
  28. public static void main(String[] args) {  
  29. new SubClass();  
  30. //oh!my god!!  
  31. }  
  32. }  

這段代碼相比上一篇,只是在子類中添加了一些成員變量。而我們的目標正是集中在討論成員變量初始化的問題上。

這段代碼的執行順序是:父類、子類實例化->調用父類構造函數->調用子類init()方法->調用子類構造函數->調用子類init()方法。最終的輸出結果向我們揭示了成員變量初始化的秘密。

當父類構造函數調用子類的init()方法的時候。子類的成員變量統統是空的,這個空是指的低級初始化。(值類型為0,布爾類型為false,引用類型為null)。而當子類構造函數調用init()方法的時候,成員變量才真正被初始化。這是一個危險的訊息,那就是使用父類構造函數調用子類時存在成員變量未初始化的風險。

我們的討論也到此為止了。再次回顧,總結一下實例何時被創建這個問題。我得出了以下結論:

本文到此便結束了。鑒于本人才疏學淺,若是專業術語有錯誤,或是哪里講的不對,也歡迎各位高手拍磚。

【編輯推薦】

  1. Java編程之四大名著
  2. 關于java數組的深度思考
  3. Java架構設計和開發中的小技巧
  4. Java編程解析節省內存效率高的方法

 

責任編輯:于鐵 來源: 中國IT實驗室
相關推薦

2011-04-11 09:39:55

對象實例

2010-10-08 10:52:36

JavaScript對

2021-04-12 07:34:03

Java集合框架

2024-05-29 08:46:19

2020-02-25 16:00:28

JavaScript數據技術

2012-01-13 12:57:48

Java

2020-10-21 14:54:02

RustGolang開發

2013-05-27 15:38:37

Java對象C++

2021-03-17 07:49:21

Java對象內存

2010-04-20 15:47:25

Oracle實例

2010-11-19 09:48:48

ORACLE創建實例

2010-06-17 18:57:11

UML對象關系

2010-09-10 15:37:44

SQL函數

2011-08-08 15:43:01

MySQL索引

2019-07-24 08:34:35

Java對象數據結構

2021-03-16 07:13:07

Java對象存儲

2021-11-26 09:00:00

數據庫數據集工具

2019-11-29 07:53:07

DNSTCP網絡協議

2010-06-29 18:58:23

UML面向對象技術

2009-08-20 17:22:45

C# FileSyst
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品国产成人国产三级 | 成人国产网站 | 国产精品视频97 | 国产成人精品久久二区二区91 | 中文字幕一区二区三区不卡在线 | 亚洲人va欧美va人人爽 | 亚洲国产精品久久久久婷婷老年 | 老司机狠狠爱 | 在线观看免费av网站 | 日本不卡一区 | 91在线视频国产 | 亚洲国产精品久久久 | 91视频一88av | 欧美精品a∨在线观看不卡 国产精品久久国产精品 | 亚洲国产激情 | 亚洲成人在线免费 | 亚洲精品乱码 | 久久亚洲欧美日韩精品专区 | 日韩成人av在线 | 国产亚洲精品综合一区 | 成人av在线播放 | 精品99久久久久久 | 国产中文字幕av | 国产亚洲精品美女久久久久久久久久 | 宅男噜噜噜66一区二区 | 亚洲劲爆av | 久久在线 | 91n成人| 国产一区在线免费 | 一级a性色生活片久久毛片波多野 | 免费av在线 | 午夜影院网站 | 久久手机视频 | 成人av免费看 | 日韩精品在线看 | 亚洲一区二区三区在线 | 日韩av看片 | 在线观看中文字幕av | 一区二区精品 | 91porn国产成人福利 | 国产超碰人人爽人人做人人爱 |