java中構(gòu)造方法及this關(guān)鍵字的用法實例詳解(超詳細)
初識構(gòu)造方法
我們上篇講了java中類的創(chuàng)建,那么讓我們來實戰(zhàn)演練一下:創(chuàng)建一個學(xué)生類,里面有學(xué)生的基本信息,包括姓名、性別、年齡、學(xué)號,你可能會寫出這樣的代碼:
class Student { String name; String gender; int age; long studentID; } public class TestDemo2 { public static void main(String[] args) { Student stu1 = new Student(); stu1.name = "張三"; // 給stu1對象的各個成員變量賦值 stu1.gender = "男"; stu1.age = 19; stu1.studentID = 231245431; // 打印輸出 System.out.println("姓名:" + stu1.name + " 性別:" + stu1.gender + " 年齡:" + stu1.age + " 學(xué)號:" + stu1.studentID); } }
??但你在寫的時候,是不是感覺給對象的成員變量一個一個的賦值太繁瑣,能不能一下子就把值賦好呢?還真能,用Java中的構(gòu)造方法就能做到這一點。
那么快來看看什么是構(gòu)造方法吧!
??構(gòu)造方法是類的一種特殊方法,用來初始化類的一個新的對象,在創(chuàng)建對象(new 運算符)之后自動調(diào)用,Java中的每個類都有一個默認的構(gòu)造方法,并且可以有一個以上的構(gòu)造方法。
Java 構(gòu)造方法有以下特點:
- 方法名必須與類名相同
- 可以有 0 個、1 個或多個參數(shù)
- 沒有任何返回值,包括 void
- 默認返回類型就是對象類型本身
- 只能與 new 運算符結(jié)合使用
??值得注意的是,如果為構(gòu)造方法定義了返回值類型或使用 void 聲明構(gòu)造方法沒有返回值,編譯時不會出錯,但 Java 會把這個所謂的構(gòu)造方法當(dāng)成普通方法來處理
??下面就是一個構(gòu)造方法的使用例子
class Student { String name; //學(xué)生類的屬性 int age; public void eat() { System.out.println(name + "在吃飯"); // 學(xué)生類的行為(方法) } public Student() { System.out.println("這是自定義的一個不帶參數(shù)的構(gòu)造方法"); } } public class TestDemo3 { public static void main(String[] args) { Student student1 = new Student(); } }
看到輸出結(jié)果,你是不是感到:咦?不對啊,我的main方法里明明就只是實例化了一個對象啊??!我沒輸出啊,為啥還會輸出構(gòu)造方法中的內(nèi)容???
Student student1 = new Student();
??原因就是:當(dāng)類的對象被創(chuàng)建時,該構(gòu)造方法將被自動調(diào)用。
??其實我們在用new關(guān)鍵字實例化對象時 , 程序一定干了這兩件事(但可能不只有這兩步)
- ??在堆區(qū)分配對象需要的內(nèi)存
- ??調(diào)用合適的構(gòu)造方法
??看到這,你可能又有問題了,我們之前實例化對象的時候明明沒定義構(gòu)造方法呀!怎么能說實例化對象時程序一定調(diào)用構(gòu)造方法呢?
??是這樣的,當(dāng)一個類中沒有提供任何構(gòu)造方法,系統(tǒng)默認提供一個無參數(shù)的構(gòu)造方法,就像這樣:
Student() {}
?? 但如果類中顯式地定義了一個或多個構(gòu)造方法,則系統(tǒng)不再提供默認構(gòu)造方法。
在一個類中,與類名相同的方法就是構(gòu)造方法。每個類可以具有多個構(gòu)造方法,但要求它們各自包含不同的方法參數(shù),比如這樣:
Student() { System.out.println("這是自定義的一個沒有參數(shù)的構(gòu)造方法"); } Student(String name) { this.name = name; System.out.println("這是自定義的帶有一個參數(shù)的構(gòu)造方法"); }
- ?? 該示例就定義了兩個構(gòu)造方法,分別是無參構(gòu)造方法和有參構(gòu)造方法。
- ??如果在一個類中定義多個具有不同參數(shù)的同名方法,稱作方法的重載。
- ??這兩個構(gòu)造方法的名稱都與類名相同,均為Student。在實例化該類時可以調(diào)用不同的構(gòu)造方法進行初始化。
構(gòu)造方法的使用
那么,就讓我們來看一下,調(diào)用構(gòu)造方法是怎樣解決上面那個麻煩的問題的,嘻嘻??
class Student { String name; String gender; int age; long studentID; // 該構(gòu)造方法可由IDEA自動生成 public Student(String name, String gender, int age, long studentID) { this.name = name; this.gender = gender; this.age = age; this.studentID = studentID; } } public class TestDemo2 { public static void main(String[] args) { Student stu1 = new Student("張三", "男", 19, 231245431); System.out.println("姓名:" + stu1.name + " 性別:" + stu1.gender + " 年齡:" + stu1.age + " 學(xué)號:" + stu1.studentID); } }
??怎么樣,是不是一下子就把值賦好,哈哈??,并且類中的構(gòu)造方法的定義還不用自己寫,在IDEA有相應(yīng)的快捷鍵可以自動生成,就像這樣:
在IDEA里點擊鼠標右鍵,彈出窗口-->在窗口中選擇Generate-->點進去后選擇Constructo-->按住ctrl鍵的同時點擊鼠標,把那幾個參數(shù)全選上,點擊OK??
嘻嘻,是不是IDEA幫你自動生成了??,方便吧
初識this
不過,構(gòu)造方法中的this.name是什么意思啊,以前不都是 "對象名.成員變量" 嗎,來接下來,我們慢慢說這個this到底是什么東東??
首先,咱先來看一段代碼??
class Date { int year; int month; int day; // 通過構(gòu)造函數(shù)傳參來賦值 public Date(int year, int month, int day) { year = year; month = month; day = day; } public void printDate() { System.out.println(year + "/" + month + "/" + day); } } public class TestDemo2 { public static void main(String[] args) { Date date1 = new Date(2022, 4, 2); date1.printDate(); } }
這段代碼有什么問題嗎?細心的同學(xué)可能以經(jīng)發(fā)現(xiàn)了 :在Date類中,傳入構(gòu)造方法的參數(shù)名稱和Date的成員變量名字相同??,那么在Date類中的構(gòu)造方法中就會出現(xiàn)一個問題:
public Date(int year, int month, int day) { // 那函數(shù)體中到底是誰給誰賦值?成員變量給成員變量?參數(shù)給參數(shù)?參數(shù)給成員變量? // 成員變量給參數(shù)?估計自己都搞不清楚了 year = year; // 當(dāng)傳入的參數(shù)相同是怎么辦! month = month; day = day; }
大家覺得在上面的main方法中會輸出什么?是2022/4/2嗎???
讓我們一起來看看吧?
??輸出竟然是0/0/0,好像我們根本沒給year,month,day賦值似的?
其實當(dāng)構(gòu)造方法的參數(shù)與類所定義的屬性同名時,對于方法中的year = year,虛擬機不清楚在這里year到底是傳過來的參數(shù)還是對象的成員變量,那么為了讓虛擬機知道我們是把參數(shù)2022賦值給當(dāng)前對象的成員變量year,我們就需要借助java中this這個關(guān)鍵字:
class Date { int year; int month; int day; // 添加了this關(guān)鍵字的構(gòu)造函數(shù) 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 class TestDemo2 { public static void main(String[] args) { Date date1 = new Date(2022, 4, 2); date1.printDate(); } }
??那為什么用this.name = name 賦值就好了呢?
this.xx的用法
??按照官方正規(guī)的解釋,this關(guān)鍵字的意義被解釋為“指向當(dāng)前對象的引用”,比如在上述代碼中當(dāng)前所實例化的對象是date1,那么this其實就指向date1,是date1的一個引用(也可以理解為是date1的一個別名)那么this.xxx其實就代表了date1.xxx??
??所以在執(zhí)行”this.name=name;”這條語句的時候,虛擬機就會把參數(shù)year的值”2022”賦值給對象date1的year成員變量。也就是說在這條賦值語句中,”=”左邊的”this.year”表示對象date1的year成員變量,而”=”右邊的year表示傳給我們構(gòu)造方法的參數(shù)。
??講到這里,有的小伙伴可能會問:”this.year”為什么不能被解釋為”當(dāng)前對象date1自己的year參數(shù)”呢???
??因為”參數(shù)”這個概念是就某個方法而言的,它相當(dāng)于某個方法的”局部變量”,只是這個”局部變量”比起在方法中定義的真正的局部變量來講有點特殊,??它能夠接收從主調(diào)方法中傳遞過來的值。因此,當(dāng)我們說到”參數(shù)”這個概念的時候,都是相對于一個”方法”而不是一個”對象”而言的,所以也就不會有”某個對象的參數(shù)”這一說法。因此,”this.year”只能被虛擬機認定為當(dāng)前對象date1自己的year成員變量,絕不會被當(dāng)作參數(shù)。
不知道大家理解??了嗎
??可能現(xiàn)在你還有點模糊,但沒關(guān)系,我們現(xiàn)在只是剛接觸到this這個關(guān)鍵字,先能模仿著用就行,以后可以慢慢理解??
??剛才我們用this.成員變量名訪問了我們當(dāng)前對象的成員變量,那么我們能不能用this.成員方法名去訪問我們的方法呢?當(dāng)然可以呀this.xxx此時的作用不就相當(dāng)于對象名.xxx嗎??,直接上代碼??
class Cat { public void jump() { System.out.println("這個貓在跳!??!"); } public void run() { this.jump(); // 在run方法中用this.方法名調(diào)用當(dāng)前對象的一個成員方法jump System.out.println("這個貓在跑?。?!"); } } public class TestDemo2 { public static void main(String[] args) { Cat cat = new Cat(); cat.run(); } }
?? 可以看出在我們成功的在run方法中用this.方法名調(diào)用了同一個類下的其他方法。
注意??:
雖然調(diào)用本類的普通方法前可以不使用this關(guān)鍵詞。但是建議追加是this,這樣的目的是可以區(qū)分方法的定義來源??
this()用于構(gòu)造函數(shù)的調(diào)用
??咱們之前說了,同一個類中可以同時有多個構(gòu)造函數(shù),通過this()還可以在一個構(gòu)造函數(shù)里調(diào)用另一個構(gòu)造函數(shù)。
class Cat { String name; int age; Cat() { System.out.println("這是自定義的一個不帶參數(shù)的構(gòu)造函數(shù)"); } public Cat(String name, int age) { this(); // 調(diào)用另一個不帶參數(shù)的構(gòu)造方法 this.name = name; this.age = age; System.out.println(this.name + this.age + "歲了"); System.out.println("這是自定義的一個帶兩個參數(shù)的構(gòu)造函數(shù)"); } } public class TestDemo2 { public static void main(String[] args) { Cat cat = new Cat("小花", 3); } }
從輸出結(jié)果可以看出通過??this(),我們成功在一個構(gòu)造方法中調(diào)用另一個不帶參數(shù)的構(gòu)造方法
??但有幾個問題需要我們注意一下
- this( ) 不能在普通方法中使用,只能寫在構(gòu)造方法中。
- 在構(gòu)造方法中使用時,必須是第一條語句。
另外,再補充一些小細節(jié)??
很多小伙伴可能不理解,為什么要通過這種方式來調(diào)用構(gòu)造方法呢?我們在上面調(diào)用Cat類中一個不帶參數(shù)的構(gòu)造方法時,難道不能直接寫一個??Cat();來調(diào)用嗎?
????????????????????????????????
??這里必須做出解釋:在Java語言中,一個類的構(gòu)造方法與類名相同。但是,一個類當(dāng)中也可以定義一個與類名相同的”普通方法”,??換句話說就是:并不是只有構(gòu)造方法與類名相同,”普通方法”也可以取和類相同的名稱(只不過全世界的程序員都不會這么干)。
??那么,在這種情況下,編譯器如何區(qū)分這個方法是”普通方法”還是”構(gòu)造方法”呢???很簡單,”普通方法”的名稱前面必須定義返回值類型,而”構(gòu)造方法”的名稱前面則沒有返回值類型的定義。這樣,編譯器就能夠分得清哪個是”構(gòu)造方法”,哪個是”和類同名的普通方法”。
??定義的時候分得清,但是在調(diào)用的時候,都是通過方法名來調(diào)用的??,這時如何分得清代碼中哪一句調(diào)用的是”構(gòu)造方法”, 哪一句調(diào)用的是”和類同名的普通方法”呢?為了解決這個問題,Java語言規(guī)定,在本類中調(diào)用構(gòu)造方法的時候,需要通過”??this(參數(shù))”的方式來調(diào)用。
總結(jié)
到此這篇關(guān)于java中構(gòu)造方法及this關(guān)鍵字用法的文章就介紹到這了,更多相關(guān)java構(gòu)造方法this關(guān)鍵字的用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java中有關(guān)構(gòu)造方法中的輸出
- Java基礎(chǔ)學(xué)習(xí)之構(gòu)造方法詳解
- java線程組構(gòu)造方法源碼解析
- 詳解Java的構(gòu)造方法及類的初始化
- 深入探究Java線程的創(chuàng)建與構(gòu)造方法
- Java字節(jié)緩存流的構(gòu)造方法之文件IO流
- Java構(gòu)造方法和方法重載詳解
- Java 構(gòu)造方法的使用詳解
- Java構(gòu)造方法 super 及自定義異常throw合集詳解用法
- java構(gòu)造器 默認構(gòu)造方法及參數(shù)化構(gòu)造方法
- Java構(gòu)造方法有什么作用?
相關(guān)文章
Spring?加載?Application?Context五種方式小結(jié)
這篇文章主要介紹了Spring?加載?Application?Context五種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。2022-01-01解決springboot讀取application.properties中文亂碼問題
初用properties,讀取java properties文件的時候如果value是中文,會出現(xiàn)亂碼的問題,所以本文小編將給大家介紹如何解決springboot讀取application.properties中文亂碼問題,需要的朋友可以參考下2023-11-11spring boot + mybatis如何實現(xiàn)數(shù)據(jù)庫的讀寫分離
這篇文章主要給大家介紹了關(guān)于spring boot + mybatis如何實現(xiàn)數(shù)據(jù)庫的讀寫分離的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09Java 內(nèi)省introspector相關(guān)原理代碼解析
這篇文章主要介紹了Java 內(nèi)省introspector相關(guān)原理代碼解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07Java設(shè)計模式編程中的工廠方法模式和抽象工廠模式
這篇文章主要介紹了Java設(shè)計模式編程中的工廠方法模式和抽象工廠模式,設(shè)計模式的建立有利于團隊協(xié)作時代碼的共同維護,需要的朋友可以參考下2016-01-01Spring中@Transactional注解關(guān)鍵屬性和用法小結(jié)
在Spring框架中,@Transactional 是一個注解,用于聲明事務(wù)性的方法,它提供了一種聲明式的事務(wù)管理方式,避免了在代碼中直接編寫事務(wù)管理相關(guān)的代碼,本文給大家介紹@Transactional 注解的一些關(guān)鍵屬性和用法,感興趣的朋友一起看看吧2023-12-12