Java-怎樣構造方法和匿名物件
前言
在編寫程式時不安全的初始化會導致程式發生發生重大錯誤。為了使程式可以被安全地初始化,C++引入了構造器(也可以成為構造方法)的概念,這是一個在建立物件時被自動呼叫的特殊方法。Java中也採用了構造器,並且提供了“垃圾回收器”。對於不在使用的記憶體資源,垃圾回收器能自動將其釋放。本篇文章主要介紹Java的構造方法以及匿名物件。
-
構造方法的定義語法與呼叫時機
-
什麼是匿名物件以及匿名物件的基本使用
構造方法的定義語法與呼叫時機
構造方法的定義語法:
構造方法是在建立物件時被編譯器自動呼叫,所以編譯器應該知道構造方法的名字然後去呼叫它,為構造方法任意取名都可能會與類的某個成員衝突。於是Java採用了同C++中一樣的方法: 構造方法採用與類相同的名稱
在Java程式設計程式碼規範中要求:“每個方法首字母小寫”,構造方法與類名是完全相同的,這個規範不適合構造方法,需要注意一下。
構造方法一般定義為如下三種方式:
class Student{ public Student(){ //① ... } ... } class Student{ Student(){ //② ... } ... } class Student{ private Student(){ //③ ... } ... }
以上三種構造方式涉及到了訪問許可權的問題:
第①種方式,構造方法採用了public修飾表示該類的物件是可以被不同包的其他類建立。
第②種方式,預設為包訪問屬性,僅限於同包的類可以建立該類的物件。
第③種方式,使用private修飾使得構造方法對外不可見,該類的物件無法被建立。多用來實現單例模式。
在上面見了三種訪問修飾符,如果學過C++那麼還知道一種沒有出現就是protected,本包中的子類可訪問,不同包中的子類可以訪問,不是子類不能訪問。
所以需要注意: 在子類中使用父類的物件或者使用其類物件訪問父類的protected成員是不行的!
這裡對包做一個解釋:包類似於電腦中的資料夾,檔案多了需要存於不同資料夾中方便管理,同樣如此,類多了就需要放在不同的包裡面方便管理。
關於被這四種修飾符修飾的屬性會方法的可訪問性做一個小結:
範圍 | private | default(什麼都不寫) | protected | public |
---|---|---|---|---|
同一個類 | O | O | O | O |
同一個包中的子類 | X | O | O | O |
同一個包中的其他類 | X | O | X | O |
不同包中的子類 | X | X | O | O |
不同包中的非子類 | X | X | X | O |
構造方法的呼叫時機:
前面一直在說構造方法的呼叫是在類建立時,與普通方法不同,構造方法在例項化新物件(使用new開闢空間後)呼叫一次。普通方法是在物件被例項化後可以呼叫多次。構造方法也可以過載(過載的概念在後面介紹)。
我們可以跟蹤一下是如何呼叫類的構造方法的。
以下面這個程式進行跟蹤:
class Person{ private long pid=123456789; public Person(){ System.out.println("Person()"); } public Person(long pid){ System.out.println("Person(long pid)"); System.out.println("在使用傳進來的pid賦值前:pid:"+this.pid); this.pid = pid; System.out.println("在使用傳進來的pid賦值後:pid:"+this.pid); } } public class Student extends Person{ //extends 實現繼承關係 private String name; private int age=0; public Student(){ System.out.println("Student()"); } public Student(long pid, String name, int age){ super(pid); //呼叫父類的建構函式一定要寫在最前面不然會報錯 System.out.println("Student(long pid, String name, int age)"); this.name = name; this.age = age; } public getName(){ return name; } public static void main(String[] args){ Student stu1 = new Student(); Student stu2 = new Student(123456,"Sakura",20); } } /* output: Person() Student() Person(long pid) 在使用傳進來的pid賦值前:pid:123456789 在使用傳進來的pid賦值後:pid:123456 Student(long pid, String name, int age) */在此我向大家推薦一個架構學習交流裙。交流學習裙號:821169538,裡面會分享一些資深架構師錄製的視訊錄影
可以輸出結果看出Java中的初始化順序如下:
- 在任何其他事情發生之前,會將分配給物件的儲存空間初始化成二進位制零。
- 呼叫基類的建構函式。
- 按照宣告順序呼叫屬性的初始化方法。在Person中先將pid賦值為1234556789然後在返回到建構函式中將123456賦值給pid。
- 呼叫匯出類的建構函式。若是Student中屬性有給定初始值,那麼依舊如第三步後再進入建構函式進行其他初始化操作。
什麼是匿名物件以及匿名物件的基本使用
什麼是匿名物件?
我們來看一步就建立物件的語法:
①類名稱 ②物件名稱 = ③new ④類名稱()
①:規定了物件的型別
②:物件的名字,唯一標識物件
③:開闢新的堆記憶體空間,儲存物件的內容,若是沒有new,則沒有記憶體空間,物件也就無法例項化
④:呼叫構造方法初始化物件
④:在此我向大家推薦一個架構學習交流裙。交流學習裙號:821169538,裡面會分享一些資深架構師錄製的視訊錄影
上面的這條語句在記憶體中開闢了兩個空間,一個棧空間儲存引用變數物件名稱,一個使用new開闢的堆空間用於儲存物件內容。
物件名稱指向了在對堆中的物件,於是我們可以使用物件名稱去操作物件。
若是我們只有"new 類名稱();"這部分的話,那就是隻是在堆中開闢了一個空間來儲存物件資訊,沒有棧去指向它。也就是這個空間是沒有名字的。
所以, 沒有棧指向的物件就叫做匿名物件 。
匿名物件的使用:
new Student(123456,"Sakura",20).getName();
由此就建立了一個匿名物件,可以向操作有名物件一樣操作它。
由於沒有引用變數指向匿名物件,所以只能使用一次,然後就會成為垃圾物件等待被GC回收,
小結
本篇博文主要總結了Java中構造方法的定義和作用(為了在類物件例項化時設定屬性初始化)由此涉及到到類訪問許可權,然後對類訪問許可權做了一個小結,以及Java程式初始化的順序。最後介紹了匿名物件,即沒有棧指向的物件。