<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
先來寫一個日期類的例子:
public class classCode { public int year; public int month; public int day; public void setDay(int y, int m, int d){ year = y; month = m; day = d; } public void printDate(){ System.out.println(year + "-" + month + "-" + day); } public static void main(String[] args) { // 構造三個日期型別的物件 d1 d2 d3 classCode Date1 = new classCode(); classCode Date2 = new classCode(); classCode Date3 = new classCode(); // 對d1,d2,d3的日期設定 Date1.setDay(2022, 8, 9); Date2.setDay(2023, 8, 9); Date3.setDay(2024, 8, 9); //列印日期的內容 Date1.printDate(); Date2.printDate(); Date3.printDate(); } }
以上程式碼定義了一個日期類,然後main方法中建立了三個物件,並通過classCode類中的成員方法對物件進行設定和列印,程式碼整體邏輯非常簡單,沒有任何問題。
有兩個需要注意的地方:
1.形參名不小心與成員變數名相同:
public void setDay(int year, int month, int day){ year = year; month = month; day = day; }
那函數體中到底是誰給誰賦值?成員變數給成員變數?引數給引數?引數給成員變數?成員變數引數?
2.三個物件都在呼叫setDate和printDate函數,但是這兩個函數中沒有任何有關物件的說明,setDate和printDate函數如何知道列印的是哪個物件的資料呢?
可以看到如果形參名和成員變數名的話,賦值以後變數的值為0,說明並沒有賦值成功。
那應該怎麼做呢?往下面看。
this參照指向當前物件(成員方法執行時呼叫該成員方法的物件),在成員方法中所有成員變數的操作,都是通過該參照去存取。只不過所有的操作對使用者是透明的,即使用者不需要來傳遞,編譯器自動完成。
改進之後的程式碼:
public void setDay(int year, int month, int day){ this.year = year; this.month = month; this.day = day; }
可以看到新增 this 參照後,賦值成功。
this 是預設新增的。即使是不加 this,也會有一個預設新增的 this。但是不新增的話,如果形參名和成員變數名相同就會帶來問題。
在下面程式碼中,可以看到三個物件都在呼叫 setDate 和 printDate 函數,而且也沒有說明,那該怎麼知道列印的是哪個物件的資料?
public static void main(String[] args) { // 構造三個日期型別的物件 Date1 Date2 Date3 Date Date1 = new Date(); Date Date2 = new Date(); Date Date3 = new Date(); // 對Date1,Date2,Date3的日期設定 Date1.setDay(2022, 8, 9); Date2.setDay(2023, 8, 9); Date3.setDay(2024, 8, 9); //列印日期的內容 Date1.printDate(); Date2.printDate(); Date3.printDate(); }
可以通過下面兩點兩點來判斷列印哪個物件:
public void setDay(Date this, int y, int m, int d){ this.year = y; this.month = m; this.day = d; } public void printDate(Date this){ System.out.println(this.year +"-"+ this.month +"-"+ this.day); }
this 的三種使用方式:
物件的參照傳遞給該成員方法,this負責來接收。
就算成員變數名與形參名不相同也建議把 this 寫上,這相當於一種保護措施,而且也是一種好的程式設計規範。
寫一個學術類,有姓名、年齡等屬性,然後通過一個方法來設定這些屬性的值,其次通過寫兩個方法,在一個方法當中使用this呼叫另一個方法。
public class Student { public String name; public int age; public void setStudent(String name, int age) { this.name = name; this.age = age; } public void printStudent() { System.out.println(this.name + "->" + this.age); } public static void main(String[] args) { Student student = new Student(); student.setStudent("zhangsan", 19); student.printStudent(); } }
通過前面知識點的學習知道,在Java方法內部定義一個區域性變數時,必須要初始化,否則會編譯失敗。
public static void main(String[] args) { int a; System.out.println(a); }// Error:(26, 28) java: 可能尚未初始化變數a.
如果是一個物件即使是沒賦值也不會報錯,因為這是一個參照變數。
public static void main(String[] args) { // 構造一個日期型別的物件 Date date = new Date(); date.setDay(2022, 8, 9); //列印日期的內容 date.printDate(); }//程式碼可以正常通過編譯
通過上述例子發現兩個問題:
這就引入了構造方法。接著往下看。
構造方法(也稱為構造器)是一個特殊的成員方法,名字必須與類名相同,在建立物件時,由編譯器自動呼叫,並且在整個物件的生命週期內只呼叫一次。
public class Student { public String name; public int age; public Student(){//這是一個構造方法 System.out.println("不帶引數的構造方法"); } public Student(String name, int age) {//這是一個構造方法 System.out.println("帶引數的構造方法"); this.name = name; this.age = age; } public void setStudent(String name, int age) { this.name = name; this.age = age; } public void printStudent() { System.out.println(this.name + "->" + this.age); } public static void main(String[] args) { Student student = new Student();//這一行是構造方法的呼叫 } }
Student student = new Student();
new在範例化物件,而範例化物件一定會呼叫構造方法。
注意:當我們沒有提供構造方法時,編譯器會自動提供一個不帶引數的構造方法。
public Student(){//不帶引數的構造方法 System.out.println("不帶引數的構造方法"); } public Student(String name, int age) {//帶兩個引數的構造方法 System.out.println("帶引數的構造方法"); this.name = name; this.age = age; }
上述兩個構造方法:名字相同,參數列不同,因此構成了方法過載。
如果使用者沒有顯式定義,編譯器會生成一份預設的構造方法,生成的預設構造方法一定是無參的。
public class Work { public int one = 1; public int three = 3; public int two = 2; public void printWork() { System.out.println(one + "-" + two + "-" + three); } public static void main(String[] args) { Work work = new Work(); work.printWork(); } }
上述Work類中,沒有定義任何構造方法,編譯器會預設生成一個不帶引數的構造方法。
那如何呼叫帶引數的構造方法呢?
public class Work { public int one = 1; public int three = 3; public int two = 2; public Work(int one, int two, int three) { System.out.println("帶引數的構造方法"); this.one = one; this.two = two; this.three = three; } public void printWork() { System.out.println(one + "-" + two + "-" + three); } public static void main(String[] args) { Work work = new Work(3, 6, 9); work.printWork(); } }
注意:一旦使用者定義,編譯器則不再生成。
構造方法中,可以通過this呼叫其他構造方法來簡化程式碼。
public Work() { this(10, 20, 30);//呼叫本類當中其他的構造方法 System.out.println("不帶引數的的構造方法"); } public Work(int one, int two, int three) { System.out.println("帶引數的構造方法"); this.one = one; this.two = two; this.three = three; }
注意:
絕大多數情況下使用public來修飾,特殊場景下會被private修飾(後序講單例模式時會遇到)
為什麼使用成員變數不需要初始化呢?
在程式層面只是簡單的一條語句,在JVM(以後講)層面需要做好多事情,下面簡單介紹下:
比如:多個執行緒同時申請物件,JVM要保證給物件分配的空間不衝突初始化所分配的空間
即:物件空間被申請好之後,物件中包含的成員已經設定好了初始值
比如:
設定物件頭資訊(關於物件記憶體模型後面會介紹)呼叫構造方法,給物件中各個成員賦值
定義成員變數的時候就已經賦值好了。
public class HardWork { public int a = 10;//就地初始化 public int b = 20;//就地初始化 public String c = "zhangsan";//就地初始化 public void setWork(int a, int b, String c) { this.a = a; this.b = b; this.c = c; } public void printWork() { System.out.println(a + "-" + b + "-" + c); } public static void main(String[] args) { HardWork work = new HardWork(); work.printWork(); System.out.println(); } }
注意:程式碼編譯完成後,編譯器會將所有給成員初始化的這些語句新增到各個建構函式中。
到此這篇關於java中的this參照及物件構造初始化的文章就介紹到這了,更多相關java this參照 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45