最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java的構(gòu)造方法及類的初始化

 更新時(shí)間:2022年08月16日 15:51:00   作者:XIN-XIANG榮  
這篇文章主要為大家詳細(xì)介紹了Java的構(gòu)造方法及類的初始化,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,感興趣的小伙伴可以了解一下

一. 利用構(gòu)造方法給對(duì)象初始化

1. 構(gòu)造方法的概念

構(gòu)造方法(也稱為構(gòu)造器)是一個(gè)特殊的成員方法,其名字必須與類名相同,在創(chuàng)建對(duì)象時(shí),由編譯器自動(dòng)調(diào)用,并且在整個(gè)對(duì)象的生命周期內(nèi)只調(diào)用一次。

構(gòu)造方法的作用就是給對(duì)象中的成員進(jìn)行初始化,并不負(fù)責(zé)給對(duì)象開辟空間。

public class Date {
    public int year;
    public int month;
    public int day;

    // 構(gòu)造方法:
    // 名字與類名相同,沒有返回值類型,設(shè)置為void也不行
    // 一般情況下使用public修飾
    // 在創(chuàng)建對(duì)象時(shí)由編譯器自動(dòng)調(diào)用,并且在對(duì)象的生命周期內(nèi)只調(diào)用一次
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int,int,int)方法被調(diào)用了");
    }

    public void printDate() {
        System.out.println(year + "-" + month + "-" + day);
    }

    public static void main(String[] args) {
        // 此處創(chuàng)建了一個(gè)Date類型的對(duì)象,并沒有顯式調(diào)用構(gòu)造方法
        Date d = new Date(2021, 6, 9);
        // 輸出Date(int,int,int)方法被調(diào)用了
        d.printDate(); // 2021-6-9
    }
}

2. 構(gòu)造方法的特性

1.名字必須與類名相同

2.沒有返回值類型,設(shè)置為void也不行

3.創(chuàng)建對(duì)象時(shí)由編譯器自動(dòng)調(diào)用,并且在對(duì)象的生命周期內(nèi)只調(diào)用一次

4.絕大多數(shù)情況下使用public來修飾,特殊場(chǎng)景下會(huì)被private修飾

5.構(gòu)造方法可以重載(用戶根據(jù)自己的需求提供不同參數(shù)的構(gòu)造方法); 下面兩個(gè)構(gòu)造方法:名字相同,參數(shù)列表不同,因此構(gòu)成了方法重載

public class Date {
    public int year;
    public int month;
    public int day;
    
    // 無參構(gòu)造方法
    public Date(){
        this.year = 1900;
        this.month = 1;
        this.day = 1;
    }
    
    // 帶有三個(gè)參數(shù)的構(gòu)造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
    }
    public static void main(String[] args) {
        Date d = new Date();
        d.printDate();
    }
}

6.如果用戶沒有顯式定義,編譯器會(huì)生成一份默認(rèn)的構(gòu)造方法,生成的默認(rèn)構(gòu)造方法一定是無參的; 一旦用戶定義,編譯器則不再生成;下面代碼中,沒有定義任何構(gòu)造方法,編譯器會(huì)默認(rèn)生成一個(gè)不帶參數(shù)的構(gòu)造方法。

public class Date {
    public int year;
    public int month;
    public int day;
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
    }
    public static void main(String[] args) {
        Date d = new Date();
        d.printDate();
    }
}

7.構(gòu)造方法中,可以通過this調(diào)用其他構(gòu)造方法來簡(jiǎn)化代碼

【注意事項(xiàng)】

  • 構(gòu)造方法中,通過this(…)去調(diào)用其他構(gòu)造方法,這條語句必須是構(gòu)造方法中第一條語句
  • 多個(gè)構(gòu)造方法不可以互相調(diào)用(不能形成環(huán)), 會(huì)形成構(gòu)造器的遞歸調(diào)用,但卻沒有調(diào)用的結(jié)束條件
public class Date {
    public int year;
    public int month;
    public int day;
// 無參構(gòu)造方法--內(nèi)部給各個(gè)成員賦值初始值,該部分功能與三個(gè)參數(shù)的構(gòu)造方法重復(fù)
// 此處可以在無參構(gòu)造方法中通過this調(diào)用帶有三個(gè)參數(shù)的構(gòu)造方法
// 但是this(2022,8,16);必須是構(gòu)造方法中第一條語句
    
    public Date(){
//System.out.println(year); 注釋取消掉,編譯會(huì)失敗
        this(2022, 8, 16);
//this.year = 1900;
//this.month = 1;
//this.day = 1;
    }
    
    // 帶有三個(gè)參數(shù)的構(gòu)造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

3. 子類構(gòu)造方法

在繼承基礎(chǔ)上,子類對(duì)象構(gòu)造時(shí),需要先調(diào)用基類構(gòu)造方法,然后執(zhí)行子類的構(gòu)造方法。

在子類構(gòu)造方法中,并沒有寫任何關(guān)于基類構(gòu)造的代碼,但是在構(gòu)造子類對(duì)象時(shí),先執(zhí)行基類的構(gòu)造方法,然后執(zhí)行子類的構(gòu)造方法,

原因在于:子類對(duì)象中成員是有兩部分組成的,基類繼承下來的以及子類新增加的部分 。父類和子類, 肯定是先有父再有子,所以在構(gòu)造子類對(duì)象時(shí)候 ,子類構(gòu)造方法中先要調(diào)用基類的構(gòu)造方法,將從基類繼承下來的成員構(gòu)造完整 ,然后再完成子類自己的構(gòu)造,將子類自己新增加的成員初始化完整 。

【注意事項(xiàng)】

1.若父類顯式定義無參或者默認(rèn)的構(gòu)造方法,在子類構(gòu)造方法第一行默認(rèn)有隱含的super()調(diào)用,即調(diào)用基類構(gòu)造方法

public class Base {
    public Base(){
        System.out.println("Base()");
    }
}

public class Derived extends Base{
    public Derived(){
// super(); // 注意子類構(gòu)造方法中默認(rèn)會(huì)調(diào)用基類的無參構(gòu)造方法:super(),
// 用戶沒有寫時(shí),編譯器會(huì)自動(dòng)添加,而且super()必須是子類構(gòu)造方法中第一條語句,
// 并且只能出現(xiàn)一次
        System.out.println("Derived()");
    }
}

public class Test {
    public static void main(String[] args) {
        Derived d = new Derived();
    }
}

2.如果父類構(gòu)造方法是帶有參數(shù)的,此時(shí)需要用戶為子類顯式定義構(gòu)造方法,并在子類構(gòu)造方法中選擇合適的父類構(gòu)造方法調(diào)用,否則編譯失敗。

public class Animal {
    public String name;
    public int  age;

   public Animal(String name, int age) {
        this.name = name;
        this.age = age;
       System.out.println("Animal(String , int )");
    }

}

public class Dog extends Animal{
    //傻狗  是狗的屬性
    public boolean silly;

   public Dog(String name,int age,boolean silly) {
        //1. 先幫助父類部分初始化 必須放到第一行
        super(name,age);
        this.silly = silly;
        System.out.println("Dog(String ,int ,boolean )");
   }
    public static void main(String[] args) {
        Animal animal2 = new Dog("金毛",6,false);
    }
}

3.在子類構(gòu)造方法中,super(…)調(diào)用父類構(gòu)造時(shí),必須是子類構(gòu)造方法中第一條語句。

4.super(…)只能在子類構(gòu)造方法中出現(xiàn)一次,由與this(…)調(diào)用時(shí)也要在第一條語句,所以super(…)不能和this(…)同時(shí)出現(xiàn),也就是是說子類構(gòu)造方法中不能使用this(…)

4. 避免在構(gòu)造方法中調(diào)用重寫的方法

一段有坑的代碼. 我們創(chuàng)建兩個(gè)類, B 是父類, D 是子類. D 中重寫 func 方法. 并且在 B 的構(gòu)造方法中調(diào)用 func

class B {
    public B() {
// do nothing
        func();
    }
    public void func() {
        System.out.println("B.func()");
    }
}
class D extends B {
    private int num = 1;
    @Override
    public void func() {
        System.out.println("D.func() " + num);
    }
}
public class Main {
    public static void main(String[] args) {
        D d = new D();
    }
}

執(zhí)行結(jié)果:

  • 構(gòu)造 D 對(duì)象的同時(shí), 會(huì)調(diào)用 B 的構(gòu)造方法.
  • B 的構(gòu)造方法中調(diào)用了 func 方法, 此時(shí)會(huì)觸發(fā)動(dòng)態(tài)綁定, 會(huì)調(diào)用到 D 中的 func
  • 此時(shí) D 對(duì)象自身還沒有構(gòu)造, num 處在未初始化的狀態(tài), 值為 0;如果具備多態(tài)性,num的值應(yīng)該是1.
  • 所以在構(gòu)造函數(shù)內(nèi),盡量避免使用實(shí)例方法,除了final和private方法。

【結(jié)論】:

“用盡量簡(jiǎn)單的方式使對(duì)象進(jìn)入可工作狀態(tài)”, 盡量不要在構(gòu)造器中調(diào)用方法(如果這個(gè)方法被子類重寫, 就會(huì)觸發(fā)動(dòng)態(tài)綁定, 但是此時(shí)子類對(duì)象還沒構(gòu)造完成), 可能會(huì)出現(xiàn)一些隱藏的但是又極難發(fā)現(xiàn)的問題.

二. 對(duì)象的默認(rèn)初始化

在Java方法內(nèi)部定義一個(gè)局部變量時(shí),用戶必須要將其賦值或者初始化,否則會(huì)編譯失?。?/p>

但對(duì)象中的字段(成員變量),用戶不需要將其初始化就可直接訪問使用,這里其原因在于new對(duì)象時(shí),jvm會(huì)給出字段的默認(rèn)初始化。

下面是new對(duì)象是時(shí),jvm層面執(zhí)行的概述:

1.檢測(cè)對(duì)象對(duì)應(yīng)的類是否加載了,如果沒有加載則加載

2.為對(duì)象分配內(nèi)存空間

3.處理并發(fā)安全問題

比如:多個(gè)線程同時(shí)申請(qǐng)對(duì)象,JVM要保證給對(duì)象分配的空間不沖突

4.初始化所分配的空間

即:對(duì)象空間被申請(qǐng)好之后,對(duì)象中包含的成員已經(jīng)設(shè)置好了初始值

數(shù)據(jù)類型默認(rèn)值
byte0
short0
int0
long0
float0.0f
double0.0
char/u0000
booleanfalse
reference (引用類型)null

5.設(shè)置對(duì)象頭信息(關(guān)于對(duì)象內(nèi)存模型后面會(huì)介紹)

6.調(diào)用構(gòu)造方法,給對(duì)象中各個(gè)成員賦值

三. 就地初始化對(duì)象

在聲明成員變量時(shí),就直接給出了初始值。

代碼編譯完成后,編譯器會(huì)將所有給成員初始化的這些語句添加到各個(gè)構(gòu)造方法中

public class Date {
    public int year = 1900;
    public int month = 1;
    public int day = 1;
    
    public Date(){
    }
    
    public Date(int year, int month, int day) {
    }
    
    public static void main(String[] args) {
        Date d1 = new Date(2022,8,16);
        Date d2 = new Date();
    }
}

四. 類的初始化順序

1. 普通類(沒有繼承關(guān)系)

靜態(tài)部分(靜態(tài)變量、常量,靜態(tài)代碼塊)

  • 在類加載階段執(zhí)行,類中存在多個(gè)靜態(tài)部分時(shí),會(huì)按順序執(zhí)行
  • 靜態(tài)代碼塊只會(huì)執(zhí)行一次,且靜態(tài)的變量、常量等只會(huì)創(chuàng)建一份

非靜態(tài)部分(實(shí)例變量、常量、實(shí)例代碼塊)

當(dāng)有對(duì)象創(chuàng)建時(shí)才會(huì)執(zhí)行,按順序執(zhí)行

最后執(zhí)行構(gòu)造方法,當(dāng)有對(duì)象創(chuàng)建時(shí)才會(huì)執(zhí)行

代碼演示:

class Person {
    public String name;
    public int age;
    public Organ organ = new Organ();
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("構(gòu)造方法執(zhí)行");
    }
    {
        System.out.println("實(shí)例代碼塊執(zhí)行");
    }
    static {
        System.out.println("靜態(tài)代碼塊執(zhí)行");
    }
}
class Organ {
    //...
    public Organ() {
        System.out.println("實(shí)例變量::organ");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Person person1 = new Person("xin",21);
        System.out.println("==============");
        Person person2 = new Person("xinxin",20);
    }
}

執(zhí)行結(jié)果:

2. 派生類( 有繼承關(guān)系)

靜態(tài)部分(靜態(tài)變量、常量,靜態(tài)代碼塊)

  • 父類靜態(tài)代碼塊優(yōu)先于子類靜態(tài)代碼塊執(zhí)行,且是最早執(zhí)行
  • 只有第一次實(shí)例化子類對(duì)象時(shí),父類和子類的靜態(tài)部分會(huì)執(zhí)行; 之后再實(shí)例化子類對(duì)象時(shí),父類和子類的靜態(tài)部分都不會(huì)再執(zhí)行

父類非靜態(tài)部分(實(shí)例變量、常量、實(shí)例代碼塊)和父類構(gòu)造方法

子類非靜態(tài)部分(實(shí)例變量、常量、實(shí)例代碼塊)和子類構(gòu)造方法

class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person:構(gòu)造方法執(zhí)行");
    }
    {
        System.out.println("Person:實(shí)例代碼塊執(zhí)行");
    }
    static {
        System.out.println("Person:靜態(tài)代碼塊執(zhí)行");
    }
}
class Student extends Person{
    public Student(String name,int age) {
        super(name,age);
        System.out.println("Student:構(gòu)造方法執(zhí)行");
    }
    {
        System.out.println("Student:實(shí)例代碼塊執(zhí)行");
    }
    static {
        System.out.println("Student:靜態(tài)代碼塊執(zhí)行");
    }
}
public class TestDemo4 {
    public static void main(String[] args) {
        Student student1 = new Student("張三",19);
        System.out.println("===========================");
        Student student2 = new Student("gaobo",20);

    }
    public static void main1(String[] args) {
        Person person1 = new Person("bit",10);
        System.out.println("============================");
        Person person2 = new Person("gaobo",20);
    }
}

執(zhí)行結(jié)果:

到此這篇關(guān)于詳解Java的構(gòu)造方法及類的初始化的文章就介紹到這了,更多相關(guān)Java初始化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • RocketMQ獲取指定消息的實(shí)現(xiàn)方法(源碼)

    RocketMQ獲取指定消息的實(shí)現(xiàn)方法(源碼)

    這篇文章主要給大家介紹了關(guān)于RocketMQ獲取指定消息的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用RocketMQ具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 學(xué)習(xí)Java之如何對(duì)時(shí)間進(jìn)行格式化

    學(xué)習(xí)Java之如何對(duì)時(shí)間進(jìn)行格式化

    當(dāng)我們?cè)谀J(rèn)情況下構(gòu)造出來的時(shí)間對(duì)象,它的時(shí)間格式并不適合我們閱讀,并且在開發(fā)時(shí),pc端、Android端、iOS端等展示的時(shí)間格式可能也并不完全一樣,本文就從這幾個(gè)問題給大家介紹如何對(duì)時(shí)間進(jìn)行格式化,感興趣的同學(xué)可以借鑒一下
    2023-05-05
  • Java中csv文件讀寫超詳細(xì)分析

    Java中csv文件讀寫超詳細(xì)分析

    CSV是一種通用的、相對(duì)簡(jiǎn)單的文件格式,其文件以純文本形式存儲(chǔ)表格數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Java中csv文件讀寫分析的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Springboot+MybatisPlus實(shí)現(xiàn)帶驗(yàn)證碼的登錄

    Springboot+MybatisPlus實(shí)現(xiàn)帶驗(yàn)證碼的登錄

    本文主要介紹了Springboot+MybatisPlus實(shí)現(xiàn)帶驗(yàn)證碼的登錄,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • java判斷回文數(shù)示例分享

    java判斷回文數(shù)示例分享

    這篇文章主要介紹了java判斷回文數(shù)示例,需要的朋友可以參考下
    2014-03-03
  • springboot整合websocket后啟動(dòng)報(bào)錯(cuò)(javax.websocket.server.ServerContainer not available)

    springboot整合websocket后啟動(dòng)報(bào)錯(cuò)(javax.websocket.server.ServerCont

    這篇文章主要介紹了springboot整合websocket后啟動(dòng)報(bào)錯(cuò)(javax.websocket.server.ServerContainer not available),通過分析錯(cuò)誤信息、排查代碼和配置,找出問題的根源,并給出相應(yīng)的解決方案,感興趣的可以了解一下
    2024-01-01
  • openEuler?搭建java開發(fā)環(huán)境的詳細(xì)過程

    openEuler?搭建java開發(fā)環(huán)境的詳細(xì)過程

    這篇文章主要介紹了openEuler?搭建java開發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • SpringBoot項(xiàng)目讀取外置logback配置文件的問題及解決

    SpringBoot項(xiàng)目讀取外置logback配置文件的問題及解決

    SpringBoot項(xiàng)目讀取外置logback配置文件的問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • springboot創(chuàng)建多module項(xiàng)目的實(shí)例

    springboot創(chuàng)建多module項(xiàng)目的實(shí)例

    這篇文章主要介紹了springboot創(chuàng)建多module項(xiàng)目的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 最新jsonwebtoken-jwt 0.12.3 基本使用小結(jié)

    最新jsonwebtoken-jwt 0.12.3 基本使用小結(jié)

    這篇文章主要介紹了最新jsonwebtoken-jwt 0.12.3 基本使用小結(jié),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-12-12

最新評(píng)論

安吉县| 民县| 宣恩县| 石泉县| 清新县| 合作市| 宁德市| 花垣县| 咸丰县| 云安县| 临颍县| 长葛市| 永定县| 泗阳县| 五台县| 甘德县| 台南市| 吴旗县| 昌吉市| 和硕县| 新郑市| 徐水县| 黑水县| 双流县| 黑龙江省| 永修县| 西城区| 马边| 门源| 祁东县| 临城县| 若尔盖县| 甘南县| 沂水县| 阜康市| 昌图县| 中方县| 外汇| 无棣县| 思南县| 高清|