1. 程式人生 > >Java入門記(三):初始化順序

Java入門記(三):初始化順序

初始化順序的規則

1.在一個類的物件例項化時,成員變數首先初始化,然後才呼叫構造器,無論書寫順序。如果呼叫構造器前,沒有顯式初始化,那麼會賦預設值。

這樣做法的原因可以理解為:構造器執行時可能會用到一些成員變數的初值。

2.static變數早於所有其他的類成員變數初始化,同樣無論書寫順序。但是static變數僅在所在類第一次被使用時初始化一次。

3.基類構造器總是在匯出類的構造過程中被呼叫,而且按照繼承層級逐漸向上連結(呼叫順序則是從基類開始向下)。可以理解為,這麼做的邏輯關係是在一個類構建時可能會用到其父類的成員、方法。在清理時順序相反。

4.成員的初始化方法(包括基本資料型別的賦值)在基類構造器呼叫之後才會被呼叫。最初時,分配給物件的儲存空間初始化二進位制的零。

例一出自《Java程式設計思想》第5.7.2節,為了便於演示初始化順序,進行了縮減和重新編號。用構造器的引數標明執行順序,演示1~2條規則:

class Bowl {
    Bowl(int marker) {
        System.out.println("Bowl(" + marker + ")");
    }
}

class Cupboard {
    Bowl bowl1 = new Bowl(3);
    static Bowl bowl2 = new Bowl(1);
    int i;
    static int j = 5;
    Cupboard() {
        System.out.println("i:" + i);
        bowl4 = new Bowl(j);
        j = 6; 
    }
    Bowl bowl3 = new Bowl(4);
    static Bowl bowl4 = new Bowl(2);
}

public class ParaInitialization {
    public static void main(String args[]) {
        new Cupboard();
        new Cupboard();
    }
}

輸出及對應註釋:

Bowl(1)      //第一個static變數
Bowl(2)      //第二個static變數
Bowl(3)      //第一個物件的第一個非static成員變數
Bowl(4)             //第一個物件的第一個非static成員變數
i:0         //未顯示初始化的成員變數
Bowl(5)      //更改static變數的值
Bowl(3)     //第二個物件的第一個非static成員變數
Bowl(4)     //第二個物件的第二個非static成員變數
i:0
Bowl(6)

  例二是一個演示第3條規則的簡單示例。

class A {
    A() {
        System.out.println("A");
    }
}

class B extends A {
    B() {
        System.out.println("B");
    }
}

class C extends B {
    C() {
        System.out.println("C");
    }
}

public class hrt {
    public static void main(String args[]) {
        new C();
    }
}

輸出

A
B
C

例三用於演示規則4。呼叫父類構造器時,構造器中的方法被子類方法覆蓋。

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 {
    int radius = 1;
    RoundGlyph(int r) {
        radius = r;
        System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
    }

    void draw() {
        System.out.println("RoundGlyph.draw(), radius = " + radius);
    }
}

public class PolyConstructors {
    public static void main(String[] args) {
        new RoundGlyph(5);
    }
}

這麼多條規則,記起來實在讓人頭大。將它們按順序編排會易讀很多。

物件初始化順序,如果有對應成員/父類的才執行對應條目:

1.將分配給物件的儲存空間初始化為二進位制的零;

2.呼叫基類構造器,從最頂層/根的基類開始;

3.按照宣告的順序,使用直接的賦值或者初始化方法,先依次初始化static變數,再依次初始化非static變數;

4.呼叫本物件所屬類的構造器。 

相關推薦

Java入門()初始順序

初始化順序的規則 1.在一個類的物件例項化時,成員變數首先初始化,然後才呼叫構造器,無論書寫順序。如果呼叫構造器前,沒有顯式初始化,那麼會賦預設值。 這樣做法的原因可以理解為:構造器執行時可能會用到一些成員變數的初值。 2.static變數早於所有其他的類成員變數初始化,同樣無論書寫順序。但是stati

Java類的各種成員初始順序父子類繼承時的靜態代碼塊,普通代碼塊,靜態方法,構造方法,等先後順

依次 成員初始化順序 main class 實例對象 變量 影響 {} 所在 class B extends A ,然後A類也就是父類裏面有靜態代碼塊,普通代碼塊,靜態方法,靜態成員變量,普通成員變量,普通方法。子類也是這樣,然後繼承之後,關於程序打印輸出的結果。涉及到Ja

Java靜態方法,靜態變數,初始順序

靜態方法的宣告和定義        定義一個靜態方法和定義一個例項方法,在形式上並沒有什麼區別,只是在宣告的頭部,需要加上一個關鍵字static。它的一般語法形式如下: [訪問許可權修飾符] static [返回值型別] 方法名([引數列表]){         語句序列 } 例如下面是一個靜態的方法: pu

淺談java類中成員的初始順序(一)

類被建立之後的成員的初始化順序到底是怎麼樣的? 首先 不考慮繼承 package com; public class DemoOne { /** * 關於類的初始化順序 */ //不考慮繼承結構的情況 private static int a;

Java類、例項的初始順序

今晚是阿里巴巴 2013 校園招聘的杭州站筆試。下午匆忙看了兩張歷年試卷,去現場打了瓶醬油。 題目總體考察點偏基礎,倒數第二題(Java 附加題)比較有趣,考察了 Java 初始化機制的細節,在此摘錄出來。 題目 求如下 java 程式碼的輸出: 1 2 3 4 5 6 7 8 9 10 11

java陣列的初始方式

2018年4月3日Java語言中陣列必須先初始化,然後才可以使用。所謂初始化就是為陣列的陣列元素分配記憶體空間,併為每個陣列元素附初始值。注意:陣列完成初始化後,記憶體空間中針對該陣列的各個元素就有個一個預設值:            基本資料型別的整數型別(byte、sho

Java入門(二)向上轉型與向下轉型

interface CanFight { void fight(); } interface CanSwim { void swim(); } interface CanFly { void fly(); } class ActionCharacter {

Java入門(四)容器關係的梳理(上)——Collection

      目錄 三、Set   Java.util中的容器又被稱為Java Collections framework。雖然被稱為框架,但是其主要目的是提供一組介面儘量簡單而且相同、並且儘量高效、以便於開發人員按照場景選用,而不

Java入門(五)容器關係的梳理(下)——Map

注意:閱讀本文及相關原始碼時,需要資料結構相關知識,包括:雜湊表、連結串列、紅黑樹。   Map是將鍵(key)對映到值(value)的物件。不同的對映不能包含相同的鍵;每個鍵最多隻能對映到一個值。下圖是常見Map的介面和實現。與Collection相比,繼承關係簡單不少。 一、Map介面和Abs

Java入門(一)折騰HelloWorld

  HelloWorld,學習每門語言的第一步。有人戲稱,這些年的程式設計生涯就是學習各種語言的HelloWorld,不知是自謙還是自嘲。目前所在的公司使用Java作為主要開發語言,我進行語言轉換也大半年了,這HelloWorld便是語言轉換的第一關。好在本科的時候學過那麼一點,而且在此之前進行了較長時間的C

java 建構函式 成員函式初始順序 以及多型的建構函式的呼叫順序

對於JAVA中類的初始化是一個很基礎的問題,其中的一些問題也是易被學習者所忽略。當在編寫程式碼的時候碰到時,常被這些問題引發的錯誤,感覺莫名其妙。 而且現在許多大公司的面試題,對於這方面的考查也是屢試不爽。不管基於什麼原因,我認為,對於java類中的初始化問

java物件建立過程及初始順序

Java虛擬機器建立一個物件都包含以下步驟: (1)給物件分配記憶體。 (2)將物件的例項變數自動初始化為其變數型別的預設值。 (3)初始化物件,給例項變數賦予正確的初始值。 對於以上第三個步驟,Java虛擬機器可採用3種方式來初始化物件,到底採用何

“全棧2019”Java第四十二章靜態程式碼塊與初始順序

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第四十二章:靜態程式碼塊與初始化順序 下一章 “全棧2019”Java第四十三章:封裝 學

【深入理解JVM】Java類繼承關係中的初始順序

Java類初始化的順序經常讓人犯迷糊,現在本文嘗試著從JVM的角度,對Java非繼承和繼承關係中類的初始化順序進行試驗,嘗試給出JVM角度的解釋。 非繼承關係中的初始化順序 對於非繼承關係,主類InitialOrderWithoutExtend中包含了靜

Java初始順序(靜態變量、靜態初始塊、實例變量、實例初始塊、構造方法)

靜態初始化 都對 class block 註釋 執行順序 blog 中一 成員變量 1、執行順序 1.1、一個類中的初始化順序 (靜態變量、靜態初始化塊)=>(變量、初始化塊、構造器)。 1.2、兩個具有繼承關系類的初始化順序 父類的(靜態變量、

Java類、實例初始順序

++ 變量 相關 obi 類加載的過程 經歷 過程 stat 布局 求如下 java 代碼的輸出?? class T implements Cloneable{ public static int k = 0; public static T t1 = ne

Java基礎初始和清理

class mil key java基礎 一個 add one his span 轉載請註明出處:jiq?欽‘s technical Blog (1) 初始化:所以假設繼承關系為:A導出B再導出C,在創建C對象的情況下的調用順序是: * (1) A的靜態域,B的靜態域

Java編程思想筆記-類的初始順序

rup cep main mark java boa marker 內存 類的初始化 1、如果有父類,先初始化父類,然後初始化子類 2、先初始化靜態成員變量、靜態代碼塊(static { }包圍的代碼),然後初始化非靜態成員變量、非靜態代碼塊(大括號包圍的代碼)。靜態成員變

java 靜態代碼塊 代碼塊 構造函數 靜態成員變量 成員變量的初始順序

總結 靜態代碼塊 變量 代碼塊 一次 初始化順序 ava 構造 成員變量 沒有父類的情況 1,靜態代碼塊-->靜態成員變量-->成員變量(實例屬性)-->代碼塊-->構造函數 2, 靜態代碼塊 和 靜態成員變量 只會初始化一次 有父類的情況 1,父類

jvm系列學習之--Java類的初始順序

parent main方法 println () 類成員 -- sys div 開始 本文主要演示Java類的初始化順序 初始化順序 對於靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序依次是(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器