1. 程式人生 > >關鍵字static及物件初始化順序

關鍵字static及物件初始化順序

以下內容參考:https://www.cnblogs.com/dolphin0520/p/3799052.html
1.static 變數
靜態變數和非靜態變數的區別:
靜態變數在方法區被所有的物件所共享,在記憶體中只有一個副本,它當且僅當在類初次載入時會被初始化。而非靜態變數是物件所擁有的,在建立物件的時候被初始化,存在多個副本,各個物件擁有的副本互不影響。
2.static方法
static方法是沒有this的,他不屬於任何物件,static方法中不能呼叫非靜態成員變數和方法。
3.static程式碼塊
static關鍵字還有一個比較關鍵的作用就是 用來形成靜態程式碼塊以優化程式效能。static塊可以置於類中的任何地方,類中可以有多個static塊。在類初次被載入的時候,會按照static塊的順序來執行每個static塊,並且只會執行一次。
一程式碼為例

package com.tunlun.App;
public class Test {
    Person person = new Person("Test");
    static Person sp = new Person("st");
    static{
        System.out.println("test static");
    }
    {
        System.out.println("1");
    }
    public Test() {
        System.out.println("test constructor"
); } public static void main(String[] args) { new MyClass(); } } class Person{ static{ System.out.println("person static"); } { System.out.println("2"); } public Person(String str) { System.out.println("person "+str); } } class MyClass extends Test { Person person = new
Person("MyClass"); static{ System.out.println("myclass static"); } { System.out.println("3"); } public MyClass() { System.out.println("myclass constructor"); } }

執行結果

person static
2
person st
test static
myclass static
2
person Test
1
test constructor
2
person MyClass
3
myclass constructor

首先我們要知道 類初始化順序是 父類靜態變數——》父類靜態程式碼塊——》子類靜態變數——》子類靜態程式碼塊——》main函式———》父類非靜態成員變數————》父類非靜態程式碼塊———》父類構造方法————》子類非靜態成員變數————》子類非靜態程式碼塊————》子類構造方法
然後我們開始分析上面程式碼。首先由於Test沒有父類直接初始化該類的靜態成員變數sp ——》進入sp沒有父類則初始化——》靜態程式碼塊——》例項程式碼塊——》構造方法————》返回Test類繼續初始化靜態程式碼塊————》主函式————》進入myclass有父類,但父類靜態變數和程式碼塊以初始過了所以初始myclass靜態方法——》然後舒適化父類成員變數person——》父類非靜態程式碼塊———》父類構造方法——》myclass父類成員變數person——》myclass非靜態程式碼塊——》myclass建構函式

下面把上面程式碼改動一下做個小測試

package com.tunlun.App;
 class Test {
    Person person = new Person("Test");
    static Person sp = new Person("sTest");
    static{
        System.out.println("test 靜態程式碼塊");
    }
    {
        System.out.println("test 非靜態程式碼塊");
    }
    public Test() {
        System.out.println("test 構造方法");
    }


}

class Person{
    static{
        System.out.println("person 靜態程式碼塊");
    }
    {
        System.out.println("Person  非靜態程式碼塊");
    }
    public Person(String str) {
        System.out.println("person "+str);
    }
}


public class MyClass extends Test {
    Person person = new Person("MyClass");
    static{
        System.out.println("myclass 靜態程式碼塊");
    }
    {
        System.out.println("myClass  非靜態程式碼塊");
    }
    public MyClass() {
        System.out.println("myclass 構造方法");
    }
    public static void main(String[] args) {
        System.out.println("主函式");
        MyClass class1 = new MyClass();
    }
}

執行結果:

person 靜態程式碼塊
Person  非靜態程式碼塊
person sTest
test 靜態程式碼塊
myclass 靜態程式碼塊
主函式
Person  非靜態程式碼塊
person Test
test 非靜態程式碼塊
test 構造方法
Person  非靜態程式碼塊
person MyClass
myClass  非靜態程式碼塊
myclass 構造方法

相關推薦

關鍵字static物件初始順序

以下內容參考:https://www.cnblogs.com/dolphin0520/p/3799052.html 1.static 變數 靜態變數和非靜態變數的區別: 靜態變數在方法區被所有的物件所共享,在記憶體中只有一個副本,它當且僅當在類初次載入時會

String str = new String("content") 建構函式有沒有返回值?new關鍵字到底在物件初始中做了什麼?

看到String str = new String("content")時想到一個問題:在我印象裡,建構函式時沒有返回值的,那麼建立的物件是如何賦值的呢?有沒有方法確定知道建構函式有沒有返回呢? 建構函式時沒有返回值的,賦值因為new關鍵字。 new的內部是呼叫了一個叫void * oper

String str = new String("content") 建構函式有沒有返回值?new關鍵字到底在物件初始中做了什麼?

看到String str = new String("content")時想到一個問題:在我印象裡,建構函式時沒有返回值的,那麼建立的物件是如何賦值的呢?有沒有方法確定知道建構函式有沒有返回呢? 建構函式時沒有返回值的,賦值因為new關鍵字。 new的內部是呼叫了一個叫v

Java 物件初始順序 執行順序

先看一道Java面試題: 求這段程式的輸出。 解答此題關鍵在於理解和掌握類的載入過程以及子類繼承父類後,重寫方法的呼叫問題: 從程式的執行順序去解答: 1.編譯;當這個類被編譯通知後,會在相應的

java 建立物件的四種方式、java物件初始順序

java建立物件的幾種方式: (1) 用new語句建立物件,這是最常見的建立物件的方法。 (2) 運用反射手段,呼叫java.lang.Class或者java.lang.reflect.Const

Java——物件初始順序

一、 程式碼塊的概念 在探究物件初始化順序之前,我們先通過程式碼來了解一下程式碼塊的概念。 class Test{ public static String str1; //靜態欄位 public String str2;

基本資料型別物件初始

Java盡力保證:所有變數在使用前都能得到恰當的初始化。 基本資料型別初始化 當作為類的成員時,即使沒有初始化,依舊會獲得一個預設值,編譯器不會報錯。 基本型別 預設

一文理解java物件初始順序

例子 ​ Talk is cheap, Show you the code! public class ParentClass { static int parentStaticField = 1; final static int parentFinalStaticField =

C++從靜態物件初始順序理解static關鍵字

問題 首先考慮一個全域性變數的初始化順序問題 在標頭檔案1中: extern int b; int a = b + 1; 在標頭檔案2中: extern int a; int b = a + 1; 原始檔中包含了標頭檔案1和標頭檔案2,這種情況下a和b可能的值是什麼呢? 雖然在開發過程一般不會出現上述這

Java基礎4——深入理解final關鍵字static關鍵字以及初始順序

深入理解final關鍵字和static關鍵字以及初始化順序 final關鍵字(基礎1中提到) final關鍵字可以修飾類、方法和引用。 修飾類,該類不能被繼承。並且這個類的物件在堆中分配記憶體後地址不可變。 修飾方法,方法不能被子類重寫。 修飾引用,引用無法改變,對於基本型別,無法修

面向物件設計中private,public,protected的訪問控制原則靜態程式碼塊的初始順序

第一:private, public, protected訪問標號的訪問範圍。private:只能由         1.該類中的函式         2.其友元函式訪問不能被任何其他訪問,該類的物件也不能訪問。protected:可以被         1.該類中的函式  

java物件建立過程初始順序

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

多重繼承關系初始順序初始

java 所有 clas 屬性 配對 -- 如果 實現 硬盤 順序:父類屬性--> 父類構造方法--> 子類屬性--> 子類構造方法 初始化: 1.在創建類之前,檢查是否已加載檢查硬盤上的.class是否加載到內存中,如果沒有加載就先加載父類的文件,再加載

EMMC驅動中常用命令說明初始順序

一、命令說明 mmc_go_idle  傳送CMD0指令,GO_IDLE_STATE  使mmc card進入idle state。  雖然進入到了Idle State,但是上電覆位過程並不一定完成了,這主要靠讀取OCR的busy位來判斷,而流程歸結為下

static和類變數與物件初始載入時機

1.static修飾的範圍 使用範圍:在Java類中,可用static修飾屬性、方法、程式碼塊、內部類 被修飾後的成員具備以下特點: 隨著類的載入而載入 優先於物件存在 修飾的成員,被所有物件所共享 訪問許可權允許時,可不建立物件,直接被類呼叫 2.類變數(cla

c# 自動實現屬性 隱式型別 物件集合初始 匿名型別

Demo  using System; using System.Collections.Generic; namespace IntelligentCompiling { class Program { static void Main(str

全域性變數、類靜態變數函式區域性靜態變數的初始順序

What is the lifetime of class static variables in C++? First the list of possibilities. Namespace Static Class Static Local Static

JAVA類初始例項初始時內部的執行順序

       記得剛畢業時,應聘JAVA開發崗位,做招聘單位的筆試時,經常有JAVA類內部的執行順序的考察,就是讓你寫出某個程式的列印結果的順序,現在整理一下。        如果一個類,有構造器,普通塊,靜態塊,那該類初始化時,它的執行順序如何呢?如果它有父類,並且它的父

從一個例項看java,new一個物件時的初始順序

例子如下: package com.zhiru; class ADemo { private static int id; static { id = 0; System.out.pri

java 用自身類的物件初始靜態變數 執行順序

    在上一篇文章中, 探索了在一條繼承鏈中靜態初始化塊和靜態變數初始化、初始化塊和例項域初始化、建構函式的執行順序(見http://blog.csdn.net/maple1997/article/details/79508981),現在繼續探索一下如果new一個自身類的物