<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            java語言

            Think in Java之構造器的真正調用順

            時間:2025-03-19 04:59:28 java語言 我要投稿
            • 相關推薦

            Think in Java之構造器的真正調用順

              構造器是OOP的重要組成部分,很多人認為它很容易。只不過是new了一個對象而已。而think in java的作者卻告訴我們,其實這并不容易。下面一起學習一下吧!

              先看下面這個例子。在你沒看結果之前,你覺得你的答案是對的么。

              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();

              }

              }

              控制臺的打印結果為:

              meal

              Lunch

              PortableLunch

              Bread

              Cheese

              Lettuce

              Sandwich

              復雜對象調用構造器的順序應該遵循下面的原則:

              1、調用基類[即父類]構造器。這個步驟會不斷反復遞歸下去,首先是構造器這種層次結構的根,然后是下一層導出類[即子類],等等。直到最底層的導出類。[從最上層的meal一直遞歸到PortableLunch]

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

              3、調用導出類構造器的主體[即Sandwich]

              可見,調用類本身是最后完成初始化的,最先完成初始化的是最頂級的基類,所謂沒有父親,哪來的兒子。處于它們中間的是調用類本身擁有的子對象。因為你不可能在子對象初始化之前用本類調用它,所以它一定在本類調用之前,父類調用之后完成初始化的。

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

              我們來看下面這個例子,來解釋為什么它不一定。因為在繼承和重寫的時候,這種情況變得有點詭異。

              深入探究:

              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

              }

              }

              控制臺打印結果:

              Glyph before draw();

              RoundGlyph.draw(),radius:0

              Glyph after draw();

              RoundGlyph(),radius:5

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

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

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

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

              調用基類[即父類]構造器。這個步驟會不斷反復遞歸下去,首先是構造器這種層次結構的根,然后是下一層導出類[即子類],等等。直到最底層的導出類。

              按聲明順序調用成員的初始化方法。

              調用導出類構造器的主體

              也就是說,實際上有4步,知道這些你對對象初始化構造器才可能有個清楚的認識。

              JAVA有更多的精髓等著人們去挖掘,而不僅僅是知道如何去使用它。

              因為你不知道什么時候它會出現意想不到的后果,而這個錯誤,可能你根本就想不出來。

              編寫構造器時有一條準則:

              用盡可能簡單的方法使對象進入正常狀態,如果可以的話,避免調用其它方法。

              在構造器內唯一能夠安全調用的那些方法是基類中的final或者private方法,這些方法不能被覆蓋,因此也就不會出現令人驚訝的問題。

              你可能無法總是遵循這條準則,但是應該朝著它努力。

              學任何語言,請打好基礎,它是你以后擴展的人生基石。

            【Think in Java之構造器的真正調用順】相關文章:

            java構造函數調用技巧10-26

            java調用的方法09-04

            Java調用瀏覽器打開網頁完整實例11-14

            java調用的幾個方法07-27

            Java調用瀏覽器打開網頁實例完整版11-06

            java調用c函數的實例09-16

            java如何構造09-21

            在Java中調用存儲的過程10-04

            Java遠程方法調用RMI08-24

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院