雲栖号資訊:【 點選檢視更多行業資訊】
在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!
前言
了解構造器之前,首先我們需要了解Java中為什麼要引入構造器,以及構造器的作用。
在很久之前,程式員們編寫C程式總會忘記初始化變量(這真的是一件瑣碎但必須的事),C++引入了 構造器(constructor) 的概念,這是一個在建立對象時被自動調用的特殊方法。Java也采用了構造器。
一、構造器的引入
引入構造器幫助我們解決了哪些問題呢?假設我們每定義一個類都必須定義一個initialize()方法,該方法提醒你,每次使用對象之前都要執行一次該方法,這意味着使用者每次都必須記得自己去調用此方法,這和上文提到的C程式員一樣,很容易就忘記了。Java構造器的出現很好的規避掉了這種問題,建立對象時,java會在使用對象之前調用相應的構造器,保證對象正确初始化。
我們來看一個簡單執行個體:
public class TestMain {
TestMain() { //預設構造器
System.out.println("預設構造器");
}
public static void main(String[] args) {
new TestMain();
}
}
//輸出
預設構造器
從這個例子我們看到了,構造器為 TestMain() ,建立對象時,會配置設定記憶體并調用對應的構造方法,可以看到輸出結果為 預設構造器 ,它已經被正确地初始化了。
二、構造器命名規則
從上面那個例子中或許已經觀察到了:類名和構造器名必須相同,是以”每個方法首字母小寫“的編碼風格并不适用于構造器。
三、注意事項
- 構造器必須與主類同名
- 構造器可以有參數
- 構造器可以重載
- 沒有傳回值
- 不添加構造器編譯器生成預設構造器
四、預設構造器
預設構造器(又名無參構造器)是沒有形式參數的,它建立的是”預設對象“。舉個栗子:
public class TestMain {
//沒有指定構造器,Java編譯器會自動生成預設構造
public static void main(String[] args) {
new TestMain();
}
}
//輸出
new TestMain()建立了一個新對象,并調用了預設構造——雖然我們并沒有主動定義它。Java規定了,如果沒有構造會生成預設構造,如果存在了一個及以上的構造便不會自動生成。
public class TestMain {
TestMain(int i) {}
TestMain(float f) {}
public static void main(String[] args) {
TestMain t1 = new TestMain(); //會報錯,沒有對應的構造方法
TestMain t2 = new TestMain(1);
TestMain t3 = new TestMain(2.0f);
}
}
//輸出
new TestMain()編譯器會報錯,因為我們沒有定義對應的無參構造方法,編譯器無法順利建立對象。如果你沒有定義構造器,編譯器會認為”你需要一個構造器,我幫你造一個“;如果你自己寫了一個構造器,編譯器會認為”你已經有構造器了,你知道自己在做什麼,我不幫你生成“。
五、構造方法重載
有預設無參構造,就有帶參構造;有帶參構造也就會發生方法重載。為了滿足不同的初始化需求,我們通常會需要定義多個帶參構造器,由于都是構造器,它們的名稱必須相同,為了讓方法名相同而參數不同的方法存在,我們就必須使用 方法重載 。它是構造器所必須的。
public class TestMain {
TestMain() {
System.out.println("預設構造");
}
TestMain(int i) {
System.out.println("int帶參構造");
}
TestMain(float f) {
System.out.println("float帶參構造");
}
public static void main(String[] args) {
TestMain t1 = new TestMain();
TestMain t2 = new TestMain(1);
TestMain t3 = new TestMain(2.0f);
}
}
//輸出
預設構造
int帶參構造
float帶參構造
從上述代碼中我們可以看到,類中定義了三個不同的構造方法,main方法中,在括号裡傳遞不同的參數,編譯器會根據參數的類型尋找對應的構造方法,進而初始化三個不同的對象,這就是構造方法的重載。
涉及基本類型的重載
在使用構造方法的重載時,我們經常會遇到将基本類型傳遞給重載方法時的一些問題。基本類型可以從一個 較小(窄類型) 類型自動提升(轉型)為一個 較大(寬類型) 類型,當涉及到方法重載時便會造成一些混淆。舉個栗子:
public class TestMain {
TestMain(int i) {
System.out.println("int帶參構造");
}
TestMain(long l) {
System.out.println("long帶參構造");
}
TestMain(double d) {
System.out.println("double帶參構造");
}
public static void main(String[] args) {
TestMain t1 = new TestMain(2.0f);
TestMain t2 = new TestMain('菌');
}
}
//輸出
double帶參構造
int帶參構造
首先,我們來看一看t1對象,建立對象時傳遞的參數是一個float類型的資料,但是結果卻顯示調用了double帶參構造,這是咋回事?其實在建立對象時,編譯器會根據傳遞參數的類型自動尋找參數類型對應的構造方法,如果沒有一模一樣的構造方法,就會尋找類型更“寬”的構造方法。t1就是典型的例子,double類型比float更“寬”(float占4位元組,double占8位元組),是以會把傳遞的參數提升。
再來看t2對象,這個對象傳遞的是char類型資料,對于char類型略有不同,如果無法找到恰好接受char參數的方法,就會把char直接提升為int。
【雲栖号線上課堂】每天都有産品技術專家分享!
課程位址:
https://yqh.aliyun.com/live立即加入社群,與專家面對面,及時了解課程最新動态!
【雲栖号線上課堂 社群】
https://c.tb.cn/F3.Z8gvnK
原文釋出時間:2020-06-10
本文作者:Aime菌
本文來自:“
掘金”,了解相關資訊可以關注“掘金”