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

Think in Java之構(gòu)造器的真正調(diào)用順序

開發(fā) 后端
構(gòu)造器是OOP的重要組成部分,很多人認(rèn)為它很容易。只不過是new了一個(gè)對(duì)象而已。而think in java的作者卻告訴我們,其實(shí)這并不容易。先看下面這個(gè)例子。在你沒看結(jié)果之前,你覺得你的答案是對(duì)的么。

構(gòu)造器是OOP的重要組成部分,很多人認(rèn)為它很容易。只不過是new了一個(gè)對(duì)象而已。而think in java的作者卻告訴我們,其實(shí)這并不容易。

先看下面這個(gè)例子。在你沒看結(jié)果之前,你覺得你的答案是對(duì)的么。

  1. package com.tudou.t1;  
  2.  
  3. class Meal {  
  4.     Meal() {  
  5.         System.out.println("meal");  
  6.     }  
  7. }  
  8.  
  9. class Bread {  
  10.     Bread() {  
  11.         System.out.println("Bread");  
  12.     }  
  13. }  
  14.  
  15. class Cheese {  
  16.     Cheese() {  
  17.         System.out.println("Cheese");  
  18.     }  
  19. }  
  20.  
  21. class Lettuce {  
  22.     Lettuce() {  
  23.         System.out.println("Lettuce");  
  24.     }  
  25. }  
  26.  
  27. class Lunch extends Meal{  
  28.     Lunch() {  
  29.         System.out.println("Lunch");  
  30.     }  
  31. }  
  32.  
  33. class PortableLunch extends Lunch{  
  34.     PortableLunch() {  
  35.         System.out.println("PortableLunch");  
  36.     }  
  37. }  
  38.  
  39. public class Sandwich extends PortableLunch {  
  40.     private Bread b = new Bread();  
  41.     private Cheese c = new Cheese();  
  42.     private Lettuce l = new Lettuce();  
  43.  
  44.     public Sandwich() {  
  45.         System.out.println("Sandwich");  
  46.     }  
  47.  
  48.     public static void main(String[] args) {  
  49.         new Sandwich();  
  50.     }  
  51. }  

控制臺(tái)的打印結(jié)果為:

meal 
Lunch 
PortableLunch 
Bread 
Cheese 
Lettuce 
Sandwich

復(fù)雜對(duì)象調(diào)用構(gòu)造器的順序應(yīng)該遵循下面的原則:

1、調(diào)用基類[即父類]構(gòu)造器。這個(gè)步驟會(huì)不斷反復(fù)遞歸下去,首先是構(gòu)造器這種層次結(jié)構(gòu)的根,然后是下一層導(dǎo)出類[即子類],等等。直到最底層的導(dǎo)出類。[從最上層的meal一直遞歸到PortableLunch]

2、按聲明順序調(diào)用成員的初始化方法。[即上面的Bread,Cheese,Lettuce]

3、調(diào)用導(dǎo)出類構(gòu)造器的主體[即Sandwich]

可見,調(diào)用類本身是最后完成初始化的,最先完成初始化的是最頂級(jí)的基類,所謂沒有父親,哪來的兒子。處于它們中間的是調(diào)用類本身擁有的子對(duì)象。因?yàn)槟悴豢赡茉谧訉?duì)象初始化之前用本類調(diào)用它,所以它一定在本類調(diào)用之前,父類調(diào)用之后完成初始化的。

那么這個(gè)說法是不是一定成立呢。結(jié)果是否定的。你必須知道JVM的編繹原理才可能知道,它究竟是如何工作的。

我們來看下面這個(gè)例子,來解釋為什么它不一定。因?yàn)樵诶^承和重寫的時(shí)候,這種情況變得有點(diǎn)詭異。

深入探究:

  1. package com.tudou.t1;  
  2.  
  3. public class ConstrcutorTest2 {  
  4.     public static void main(String[] args) {  
  5.         new RoundGlyph(5);  
  6.     }  
  7. }  
  8.  
  9. class Glyph {  
  10.  
  11.     void draw() {  
  12.         System.out.println("Glyph draw()");  
  13.     }  
  14.  
  15.     Glyph() {  
  16.         System.out.println("Glyph before draw();");  
  17.         draw();  
  18.         System.out.println("Glyph after draw();");  
  19.     }  
  20. }  
  21.  
  22. class RoundGlyph extends Glyph {  
  23.     private int radius = 1;  
  24.  
  25.     RoundGlyph(int r) {  
  26.         radius = r;  
  27.         System.out.println("RoundGlyph(),radius:" + radius);  
  28.     }  
  29.  
  30.     void draw() {  
  31.         System.out.println("RoundGlyph.draw(),radius:" + radius);//此處打印是0,而不是1  
  32.     }  

控制臺(tái)打印結(jié)果:

Glyph before draw(); 
RoundGlyph.draw(),radius:0 
Glyph after draw(); 
RoundGlyph(),radius:5

為什么RoundGlyph.draw(),radius:0這里會(huì)是0呢。

默認(rèn)的1哪去了?值自己會(huì)變么。其實(shí)上面的講述并不完整。,而這正是解決謎題的關(guān)鍵所在。初始化的實(shí)際過程之前,實(shí)際在還有一步。

0:在其他任何事物發(fā)生之前,將分配對(duì)象的存舍得空間初始化為二進(jìn)制的零。

而它后面的初始化順序就是上面的3步。

  1. 調(diào)用基類[即父類]構(gòu)造器。這個(gè)步驟會(huì)不斷反復(fù)遞歸下去,首先是構(gòu)造器這種層次結(jié)構(gòu)的根,然后是下一層導(dǎo)出類[即子類],等等。直到最底層的導(dǎo)出類。
  2. 按聲明順序調(diào)用成員的初始化方法。
  3. 調(diào)用導(dǎo)出類構(gòu)造器的主體

也就是說,實(shí)際上有4步,知道這些你對(duì)對(duì)象初始化構(gòu)造器才可能有個(gè)清楚的認(rèn)識(shí)。

JAVA有更多的精髓等著人們?nèi)ネ诰颍粌H僅是知道如何去使用它。

因?yàn)槟悴恢朗裁磿r(shí)候它會(huì)出現(xiàn)意想不到的后果,而這個(gè)錯(cuò)誤,可能你根本就想不出來。

編寫構(gòu)造器時(shí)有一條準(zhǔn)則:

用盡可能簡單的方法使對(duì)象進(jìn)入正常狀態(tài),如果可以的話,避免調(diào)用其它方法。

在構(gòu)造器內(nèi)唯一能夠安全調(diào)用的那些方法是基類中的final或者private方法,這些方法不能被覆蓋,因此也就不會(huì)出現(xiàn)令人驚訝的問題。

你可能無法總是遵循這條準(zhǔn)則,但是應(yīng)該朝著它努力。

學(xué)任何語言,請(qǐng)打好基礎(chǔ),它是你以后擴(kuò)展的人生基石。

原文鏈接:http://blog.csdn.net/yaerfeng/article/details/7294882

【編輯推薦】

  1. 用Java編寫你自己的簡單HTTP服務(wù)器
  2. Java一次性查詢幾十萬 幾百萬數(shù)據(jù)解決辦法
  3. MindTerm 4.0發(fā)布 基于Java的SSH客戶端
  4. 有可能挑戰(zhàn)Java優(yōu)勢(shì)的四種技術(shù)
  5. Think in Java之斐波那契數(shù)列
責(zé)任編輯:林師授 來源: yaerfeng的博客
相關(guān)推薦

2012-05-16 13:45:24

Java構(gòu)造器

2022-01-04 19:33:03

Java構(gòu)造器調(diào)用

2012-02-22 10:14:44

Java

2009-07-21 12:35:00

Scala從構(gòu)造器

2009-09-18 13:40:40

繼承關(guān)系

2010-01-11 16:31:54

C++優(yōu)化器

2019-10-22 08:45:07

Java構(gòu)造器編程語言

2009-07-17 17:41:41

SwingWorker

2020-10-29 11:04:28

緩存瀏覽器LocalStorag

2022-12-09 08:19:43

HTTP協(xié)議MIME

2011-05-16 10:35:02

jQuery

2009-07-22 08:45:35

Scala超類構(gòu)造器override修飾符

2009-08-14 09:15:28

C#調(diào)用構(gòu)造函數(shù)

2017-04-21 08:18:14

Java程序員反射機(jī)制

2024-01-25 11:38:11

AI數(shù)據(jù)

2012-07-10 01:51:43

代碼架構(gòu)設(shè)計(jì)

2012-04-20 14:44:11

JavaScript

2009-12-10 13:37:16

PHP parent

2011-12-10 19:17:12

webOS

2014-11-25 09:44:43

SDN
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 麻豆久久久久久久 | 日韩欧美在线观看视频 | 久久九精品 | 成人欧美一区二区三区1314 | 韩国主播午夜大尺度福利 | 精品在线一区二区三区 | 一区二区在线免费观看视频 | 欧美一区二区三区免费在线观看 | 中文一区二区视频 | 国产精彩视频在线观看 | 欧美xxxx性 | 久久亚洲一区 | 日韩高清在线 | 91欧美精品成人综合在线观看 | 日韩在线观看网站 | 国产精品一区二区久久久久 | 超碰成人在线观看 | 国产精品一级 | 免费观看黄色一级片 | 欧美一级特黄aaa大片在线观看 | 91福利在线导航 | 色综合天天天天做夜夜夜夜做 | 亚洲二区视频 | 国产精品99 | 国产99免费视频 | 日韩免费视频一区二区 | 久久香蕉网 | 国产精品999| 午夜激情免费 | av在线黄| 人碰人操| 精品久久精品 | 天天插天天操 | 成人久久一区 | av中文在线 | 国产电影一区二区 | www.精品一区| 天堂资源 | a免费视频 | 国产在线播放一区二区三区 | 国产免费福利 |