Java?超詳細講解對象的構(gòu)造及初始化
如何初始化對象
我們知道再Java方法內(nèi)部定義一個局部變量的時候,必須要初始化,否則就會編譯失敗
要讓這串代碼通過編譯,很簡單,只需要在正式使用a之前,給a設(shè)置一個初始值就好
那么對于創(chuàng)造好的對象來說,我們也要進行相對應(yīng)的初始化
我們先寫一個Mydate的類
public class MyDate { public int year; public int month; public int day; /** * 設(shè)置日期: */ public void setDate(int year,int month,int day) { this.year = year; this.month = month ; this.day = day; } public void printDate() { System.out.println("年:"+this.year+"月:"+this.month+"日:"+this.day); } public static void main(String[] args) { // this.printDate(); MyDate myDate = new MyDate(); myDate.setDate(2022,3,25); myDate.printDate(); MyDate myDate2 = new MyDate(); myDate2.setDate(2022,3,28); myDate2.printDate(); } }
我們可以看到,在Mydate類中,要在調(diào)用之前實現(xiàn)寫好setDate才能將具體的日期設(shè)置到對象當中
我們通過這個例子就可以發(fā)現(xiàn)兩個問題:
- 每次對象創(chuàng)建好之后調(diào)用setDate方法設(shè)置具體時期,比較麻煩,那么對象該如何初始化呢?
- 局部變量必須要初始化之后才能使用,那么為什么字段聲明之后沒有給初值,它依舊可以使用呢?
答案:
- 我們可以運用構(gòu)造函數(shù)來進行初始化
- 因為這里和main函數(shù)中定義的局部變量不同,編譯器會自動為你的字段聲明的局部變量賦初始零值。
構(gòu)造方法
當我們實例化一個對象的時候:必須會有這兩步,但并不是一定只有這兩步
- 為對象分配內(nèi)存
- 調(diào)用合適的構(gòu)造方法
構(gòu)造方法(也稱為構(gòu)造器)是一個特殊的成員方法,名字必須與類名相同,在創(chuàng)建對象的時候,由編譯器自動調(diào)用,并且在整個對象的生命周期內(nèi)只調(diào)用一次
class Person { public String name; public int age; //構(gòu)造方法: //名字與類名相同,且沒有返回值類型,void也不行 //一般情況下使用public修飾 //在創(chuàng)建對象的時候由編譯器自動調(diào)用,并且在對象的聲明周期內(nèi)只調(diào)用一次 public Person(String name,int age){ this.name = name; this.age = age; System.out.println("構(gòu)造方法被調(diào)用了") } public void eat() { System.out.println("吃飯!"); } public void sleep() { System.out.println("睡覺!"); } public static void main(String[] args){ //在此處創(chuàng)建了一個Date類型的對象,并沒有顯式調(diào)用構(gòu)造函數(shù) Person p = new Person("xiaohong",18); p.eat(); } }
??:構(gòu)造方法的作用就是對對象中的成員進行初始化,并不負責(zé)給對象開辟空間
特性
- 名字必須和類名相同
- 沒有返回值類型,void也不行
- 創(chuàng)建對象時由編譯器自動調(diào)用,并且在對象的生命周期內(nèi)只調(diào)用一次(相當于人的出生)
- 構(gòu)造方法可以重載(用戶根據(jù)自己的需求提供不同參數(shù)的構(gòu)造方法)
class Student { //屬性:成員變量-》類的內(nèi)部 方法的外部的 public String name; public int age; public double score ; public String sex; public Student() { //調(diào)用本類中 帶有2個參數(shù)的構(gòu)造方法,第一個參數(shù)的類型是String,第2個參數(shù)的類型是int this.age = 18; System.out.println("這個是不帶參數(shù)的構(gòu)造方法!"); } public Student(String name,int age) { //this(); this.age = age; this.name = name; System.out.println("這個是帶2個參數(shù)的構(gòu)造方法!"); } public Student(String name, int age, double score, String sex) { this.name = name; this.age = age; this.score = score; this.sex = sex; System.out.println("帶4個參數(shù)的構(gòu)造方法!"); } public void doClass() { System.out.println(name+"正在上課!"); //this.doHomeWork(); } public void doHomeWork(){ System.out.println(name+"正在寫作業(yè)"); } public void show() { System.out.println("姓名:"+name+" 年齡:"+age+" 學(xué)分:"+score+" 性別:"+sex); } } //重載的時候
上述方法中:名字相同,參數(shù)列表不同,因此構(gòu)成了方法重載
如果用戶沒有顯式定義,編譯器會生成一份默認的構(gòu)造方法,生成的默認構(gòu)造方法一定是無參的。
class MyGirlFired { public String name; public int age; public String eyes; public void eat() { System.out.println("吃火鍋!"); } }
在上面的代碼中,沒有定義任何構(gòu)造方法,編譯器就會默認為我們生成一個不帶參數(shù)的構(gòu)造方法
??:一旦用戶定義了,編譯器則不再生成任何構(gòu)造函數(shù)
class MyGirlFired { public String name; public int age; public String eyes; public MyGirlFired(String name,int age){ this.name = name; this.age = age; } public void eat() { System.out.println("吃火鍋!"); } public static void main(String[] args) { //如果編譯器會生成,則生成的構(gòu)造方法一定是無參數(shù)的 //則此處創(chuàng)建對象是可以通過編譯的 //但實際上會報錯 MyGirlFired xHong = new MyGirlFired(); } }
在構(gòu)造方法中,可以通過this調(diào)用其他構(gòu)造方法來簡化代碼
class Student { //屬性:成員變量-》類的內(nèi)部 方法的外部的 public String name; public int age; public double score ; public String sex; public Student() { //調(diào)用本類中 帶有2個參數(shù)的構(gòu)造方法,第一個參數(shù)的類型是String,第2個參數(shù)的類型是int this("yumi",18); //this("bit3",99,98.9,"女"); System.out.println("這個是不帶參數(shù)的構(gòu)造方法!"); } public Student(String name,int age) { //this(); this.age = age; this.name = name; System.out.println("這個是帶2個參數(shù)的構(gòu)造方法!"); } public Student(String name, int age, double score, String sex) { this.name = name; this.age = age; this.score = score; this.sex = sex; System.out.println("帶4個參數(shù)的構(gòu)造方法!"); } public void doClass() { System.out.println(name+"正在上課!"); //this.doHomeWork(); } public void doHomeWork(){ System.out.println(name+"正在寫作業(yè)"); } public void show() { System.out.println("姓名:"+name+" 年齡:"+age+" 學(xué)分:"+score+" 性別:"+sex); } }
??注意:
- this()必須是構(gòu)造方法中的第一條語句,且只能放在構(gòu)造函數(shù)中
- 不能形成“環(huán)”
例如
絕大多數(shù)情況我們都用public來修飾,特殊場景下會被private修飾
默認初始化
上面我們提到了一個問題:為什么局部變量在使用時必須要用初始化,而成員變量可以不用呢?
public class Date { public int year; public int month; public int day; public Date(int year,int month,int day){ //成員變量在定義之前,并沒有給出初始值,那為什么就可以使用呢? System.out.println(this.year); System.out.println(this.month); System.out.println(this.day); } public static void main(String[] args) { //此處a并沒有初始化,編譯器報錯; //Error:(24,28)Java:可能尚未初始化變量a //int a; //System.out.println(a); Date d = new Date(2022,3,29); } }
要搞清楚這個過程,我們需要知道new關(guān)鍵字背后所發(fā)生的一些事情
Date d = new Date(2021,6,9);
在程序?qū)用嬷皇呛唵蔚囊粭l語句,而在JVM層面則需要做好多事情
- 檢測對象對應(yīng)的類是否加載了,如果沒有加載則加載
- 為對象分配內(nèi)存空間
- 處理并發(fā)安全問題
??比如:多個線程同時申請對象,JVM要保證給對象分配的空間不沖突
- 初始化所分配的空間
即:對象空間被申請好了之后,對象中包含的成員已經(jīng)設(shè)置好了初始值
數(shù)據(jù)類型 | 默認值 |
---|---|
byte | 0 |
char | ‘\u0000’ |
short | 0 |
int | 0 |
long | 0L |
boolean | false |
float | 0.0f |
double | 0.0 |
reference | null |
- 設(shè)置對象頭信息(關(guān)于對象內(nèi)存模型后面再說)
- 調(diào)用構(gòu)造方法,是給對象中的各個成員賦值
就地初始化
在聲明成員變量時,就直接給出了初始值
public class Date { public int year; public int month; public int day; public Date(){ System.out.println(this.year); System.out.println(this.month); System.out.println(this.day); } public Date(int year,int month,int day){ //成員變量在定義之前,并沒有給出初始值,那為什么就可以使用呢? System.out.println(this.year); System.out.println(this.month); System.out.println(this.day); } public static void main(String[] args) { //此處a并沒有初始化,編譯器報錯; //Error:(24,28)Java:可能尚未初始化變量a //int a; //System.out.println(a); Date d1 = new Date(2022,3,29); Date d2 = new Date(); } }
//運行結(jié)果:
//0
//0
//0
//0
//0
//0
??注意:代碼編譯完成之后,編譯器會將所有成員初始化的這些語句添加到各個構(gòu)造函數(shù)中
5.一個類至少會有1個構(gòu)造函數(shù),就算你沒有寫!
6.構(gòu)造方法 本質(zhì) 就是來實例化對象的時候調(diào)用
(1)分配內(nèi)存
(2)調(diào)用合適的構(gòu)造方法
7.this可以用來調(diào)用本類中的其他構(gòu)造方法【構(gòu)造方法當中使用】
且必須放在第一行!所以,只能在當前構(gòu)造方法當中,調(diào)用一次
8.this的用法:
- this.data 訪問屬性
- this.func(); 訪問方法
- this(); //用來調(diào)用本類中的其他構(gòu)造方法
9.this不能形成環(huán)。
有錯誤請大家批評指正
感謝閱讀
到此這篇關(guān)于Java 超詳細講解對象的構(gòu)造及初始化的文章就介紹到這了,更多相關(guān)Java 對象的構(gòu)造內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Spring的@Transaction導(dǎo)致數(shù)據(jù)庫回滾全部生效問題(又刪庫跑路)
使用@Transactional一鍵開啟聲明式事務(wù), 這就真的事務(wù)生效了?過于信任框架總有“意外驚喜”。本文通過案例給大家詳解關(guān)于Spring的@Transaction導(dǎo)致數(shù)據(jù)庫回滾全部生效問題,感興趣的朋友一起看看吧2021-05-05Mac M1 Java 開發(fā)環(huán)境配置詳解
這篇文章主要介紹了Mac M1 Java 開發(fā)環(huán)境配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03詳解Java兩種方式簡單實現(xiàn):爬取網(wǎng)頁并且保存
本篇文章主要介紹了Java兩種方式簡單實現(xiàn):爬取網(wǎng)頁并且保存 ,主要用UrlConnection、HttpClient爬取實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-12-12