輕輕鬆鬆瞭解Java的初始化方法(含對象數組的小問題)

Java基礎複習6—初始化

之前講過了類的一些基礎,想必大家都知道了類的定義

什麼?你忘了?

下面給你一個例子快速複習

class AClass{
    int a;
    boolean b;
    void getA(){
        return this.a;
    }
    AClass(){
        System.out.println("這是構造函數被調用");
    }
}

int a是類的屬性

getA()是類的方法

統一使用getName()與setName()方法來對對象的屬性進行取與設置的操作

AClass()是類的構造函數,名字與類相同,沒有返回值

好了好了,別說了,我已經看夠了

那現在上主菜,Java中的初始化

1.指定初始化

獲取你是有C++基礎的開發者,你一定知道初始化的一個禁忌,直接在類中就地初始化。

Java中最簡單的初始化——指定初始化

你哪個變量需要初始化,就直接賦值給他就好了嘛。

如下,直接給賦值。

class AClass{
    int a=5;
    boolean b=true;
    void getA(){
        return this.a;
    }
    AClass(){
        System.out.println("這是構造函數被調用");
    }
}

那對於非基本類型的對象,怎麼辦?

在這裏插入圖片描述

簡單,對於基礎類型,初始化的方法是賦值,對於類?

你已經知道了,使用new關鍵字

如下

class AClass{
    int a=5;
    boolean b=true;
    AnotherClass c = new AnotherClass();
    void getA(){
        return this.a;
    }
    AClass(){
        System.out.println("這是構造函數被調用");
    }
}

總結一下,指定初始化的方式允許程序員直接給類的成員設置初始值,如果是對象,設置初始值的方式是new

2.構造器初始化

顧名思義,之前我們不是說過有一個構造方法嘛:快速回顧什麼是構造方法?

哇,兄弟你又忘了?
在這裏插入圖片描述

我們再來看一波概念:

構造方法解決的問題是:在調用一個類之前,都需要調用initialize()方法。通過調用initialize()方法,我們可以搭建一個構造器,保證所有的對象都會得到初始化。

就是說,new對象會使用對應的構造方法,置於是哪個方法,看你的參數了

那可以初始化一個類,我們順便把類的屬性一起初始化了就行了嘛

直接上例子

class AClass{
    int a=5;
    boolean b=true;
    AnotherClass c = new AnotherClass();
    void getA(){
        return this.a;
    }
    //不刪除他的原因是爲了不給參數也能生成對象
    AClass(){
        System.out.println("這是構造函數被調用");
    }
    //個人習慣使用this,如果你的參數沒有與屬性名字衝突,可以不用this,
    //個人認爲使用這種方式更能體現他是個“構造器初始化”
    AClass(int a,boolean b,AnotherClass c){
        this.a=a;
        this.b=b;
        //注意這裏的對象賦值是引用,實際上沒有新建對象,想新建對象就new
        this.c=c;
    }
}

再在這裏提醒一遍:引用與對象是不同的,這裏構造器是把引用指向了另一個對象,並沒有新建對象

不過不需要擔心這個對象死去導致空指針異常,你已經是一個成熟的Java人了滑稽。

因爲Java不允許用戶自行回收內存,而這裏的引用相當於兩個對象直接有了聯繫,所以AClass對象消失之前,內部對象是不會消失滴!不懂?看之前的文章嘛《讓你第一次認識到Java的內存管理》

3.靜態數據的初始化

靜態,靜態,靜態是什麼意思?

你可以幻想自己在Java的虛擬機之中,每個對象都有自己的空間,存了屬於對象自己的數據,這叫動態

靜態呢?剛好相反,靜態的是數據是類共享的,只佔用了一份存儲區域。

靜態是指共享,一份,而並不是最終,所以我們仍可以修改靜態參數,但是這是很不推薦的行爲,畢竟是公家的數據,你一個對象修改了,別不就遭了,同時也有大佬遇到了利用靜態的原理反而翻車的情況——分佈式。

靜態數據初始化沒什麼特殊的,與非靜態相同。

class AClass{
    static int a=5;
    boolean b=true;
    static AnotherClass c = new AnotherClass();
    void getA(){
        return this.a;
    }
    AClass(){
        System.out.println("這是構造函數被調用");
    }
}

哇,每次都要寫static,好累啊

恭喜你,Java還真的有解決這個的方案

在這裏插入圖片描述

用一個例子,直接說明,這叫顯示靜態初始化

class AClass{
    boolean b=true;  
    static{
        int a=5;
        AnotherClass c = new AnotherClass();
    }
    void getA(){
        return this.a;
    }
    AClass(){
        System.out.println("這是構造函數被調用");
    }
}

這非靜態的就不服了,你們靜態可以,我們非靜態也可以,誒確實,真的可以

這就是實例初始化

class AClass{
    boolean b=true;  
    {
        int a=5;
        AnotherClass c = new AnotherClass();
    }
    void getA(){
        return this.a;
    }
    AClass(){
        System.out.println("這是構造函數被調用");
    }
}

4.那初始化的順序呢?

綜合上面的講述,我們有構造器初始化,靜態,直接初始化這三種情況

講順序之前,請先回顧一下靜態屬性的位置

哦,你應該知道了,靜態屬性的只有一個,歸屬於類。
在這裏插入圖片描述

那肯定靜態是排第一嘛!

老二是誰嘞,我們思考一下,構造方法有多種,所以會不會用到全部初始化的構造方法還不一定,那一定會用到的是誰嘞,直接初始化!

好的直接初始化排老二!

最後就是構造方法嘍

所以綜上,再加點調料,順序如下:

  1. 在類被載入時,有關靜態初始化的操作會執行(靜態初始化只在Class對象首次加載使進行一次),值的一提的是,靜態成員只有在使用到的時候纔會被初始化(類.名字進行訪問&初始化對象)
  2. 在堆上爲對象分配空間
  3. 存儲空間清零,所有數據爲默認(安全)
  4. 執行在字段處定義的初始化操作
  5. 執行構造器

外傳:數組初始化

爲什麼要單獨寫數組呢

主要是忘了寫

開玩笑開玩笑,數組並不能算一種新的初始化方法(個人認爲),他的初始化模式與之前的相似。

在介紹之前,還是先看看什麼是數組:

數組:相同類型元素緊密排列。提煉出來差不多就是這樣。

烤羊肉串

比如這個烤羊肉串(我沒有誘惑你),羊肉串是類型相同的,然後一個一個排列在一起。

Java怎麼實現一個數組?

兩種形式

  1. type[] name; //Java 新增的方式
  2. type name[];//傳統C語言風格

那總要一種推薦的嘛

本人選擇type[] name;原因是更有類型的意味,數組在Java中可以算一個特殊的對象了。

如何初始化?

兩種

第一個,直接初始化

(有什麼奧祕嘛,直接用{}就能初始化)

例子給你了

int[] a1={1,2,3,4};

這裏必須要提到,這種方式並沒有直接表明數組的長度,個人還是喜歡第二種,不過某些場景還是這種方便

數組越界的問題

C和C++中是默認“允許”數組越界的,程序不會報錯,反而能正常運行,不過結果可想而知

Java中,數組越界則會出現RuntimeError(運行時異常),保護程序

第二種,使用new關鍵字

是不是有類的味道了呢?

int[] a1= new int[5];

另外對於對象數組,必須再次瞭解一點:引用≠對象

所以當下次你再創建了一個下面的對象數組

ClassName[] b= new ClassName[15];

還沒有給對象數組中的引用賦值報錯了

在這裏插入圖片描述

就再強調一遍,Java初始化對象的辦法只有new,所以其他各種莫名其妙的都沒有初始化哦,要用其他語言當我沒說。

聲明瞭一個對象數組,還需要初始化纔能有實際的內容,

小心使得萬年船哦。

萬水千山都是情,求個贊兒行不行!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章