亚洲一级免费看,特黄特色大片免费观看播放器,777毛片,久久久久国产一区二区三区四区,欧美三级一区二区,国产精品一区二区久久久久,人人澡人人草

java語(yǔ)言

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

時(shí)間:2025-03-19 04:59:28 java語(yǔ)言 我要投稿
  • 相關(guān)推薦

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

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

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

  package com.tudou.t1;

  class Meal {

  Meal() {

  System.out.println("meal");

  }

  }

  class Bread {

  Bread() {

  System.out.println("Bread");

  }

  }

  class Cheese {

  Cheese() {

  System.out.println("Cheese");

  }

  }

  class Lettuce {

  Lettuce() {

  System.out.println("Lettuce");

  }

  }

  class Lunch extends Meal{

  Lunch() {

  System.out.println("Lunch");

  }

  }

  class PortableLunch extends Lunch{

  PortableLunch() {

  System.out.println("PortableLunch");

  }

  }

  public class Sandwich extends PortableLunch {

  private Bread b = new Bread();

  private Cheese c = new Cheese();

  private Lettuce l = new Lettuce();

  public Sandwich() {

  System.out.println("Sandwich");

  }

  public static void main(String[] args) {

  new Sandwich();

  }

  }

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

  meal

  Lunch

  PortableLunch

  Bread

  Cheese

  Lettuce

  Sandwich

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

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

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

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

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

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

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

  深入探究:

  package com.tudou.t1;

  public class ConstrcutorTest2 {

  public static void main(String[] args) {

  new RoundGlyph(5);

  }

  }

  class Glyph {

  void draw() {

  System.out.println("Glyph draw()");

  }

  Glyph() {

  System.out.println("Glyph before draw();");

  draw();

  System.out.println("Glyph after draw();");

  }

  }

  class RoundGlyph extends Glyph {

  private int radius = 1;

  RoundGlyph(int r) {

  radius = r;

  System.out.println("RoundGlyph(),radius:" + radius);

  }

  void draw() {

  System.out.println("RoundGlyph.draw(),radius:" + radius);//此處打印是0,而不是1

  }

  }

  控制臺(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í)際過(guò)程之前,實(shí)際在還有一步。

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

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

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

  按聲明順序調(diào)用成員的初始化方法。

  調(diào)用導(dǎo)出類(lèi)構(gòu)造器的主體

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

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

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

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

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

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

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

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

【Think in Java之構(gòu)造器的真正調(diào)用順】相關(guān)文章:

java構(gòu)造函數(shù)調(diào)用技巧10-26

java調(diào)用的方法09-04

Java調(diào)用瀏覽器打開(kāi)網(wǎng)頁(yè)完整實(shí)例11-14

java調(diào)用的幾個(gè)方法07-27

Java調(diào)用瀏覽器打開(kāi)網(wǎng)頁(yè)實(shí)例完整版11-06

java調(diào)用c函數(shù)的實(shí)例09-16

java如何構(gòu)造09-21

在Java中調(diào)用存儲(chǔ)的過(guò)程10-04

Java遠(yuǎn)程方法調(diào)用RMI08-24