前言
在編寫程序時(shí)不安全的初始化會(huì)導(dǎo)致程序發(fā)生發(fā)生重大錯(cuò)誤。為了使程序可以被安全地初始化,C++引入了構(gòu)造器(也可以成為構(gòu)造方法)的概念,這是一個(gè)在創(chuàng)建對象時(shí)被自動(dòng)調(diào)用的特殊方法。Java中也采用了構(gòu)造器,并且提供了“垃圾回收器”。對于不在使用的內(nèi)存資源,垃圾回收器能自動(dòng)將其釋放。本篇文章主要介紹Java的構(gòu)造方法以及匿名對象。
構(gòu)造方法的定義語法與調(diào)用時(shí)機(jī)
什么是匿名對象以及匿名對象的基本使用
構(gòu)造方法的定義語法與調(diào)用時(shí)機(jī)
構(gòu)造方法的定義語法:
構(gòu)造方法是在創(chuàng)建對象時(shí)被編譯器自動(dòng)調(diào)用,所以編譯器應(yīng)該知道構(gòu)造方法的名字然后去調(diào)用它,為構(gòu)造方法任意取名都可能會(huì)與類的某個(gè)成員沖突。于是Java采用了同C++中一樣的方法:構(gòu)造方法采用與類相同的名稱。
在Java編程代碼規(guī)范中要求:“每個(gè)方法首字母小寫”,構(gòu)造方法與類名是完全相同的,這個(gè)規(guī)范不適合構(gòu)造方法,需要注意一下。
構(gòu)造方法一般定義為如下三種方式:
class Student{
? public Student(){? ? //①
? ? ...
? }
? ...
}
class Student{
? Student(){? ? ? //②
? ? ...
? }
? ...
}
class Student{
? private Student(){? ? //③
? ? ...
? }
? ...
}
以上三種構(gòu)造方式涉及到了訪問權(quán)限的問題:
第①種方式,構(gòu)造方法采用了public修飾表示該類的對象是可以被不同包的其他類創(chuàng)建。
第②種方式,默認(rèn)為包訪問屬性,僅限于同包的類可以創(chuàng)建該類的對象。
第③種方式,使用private修飾使得構(gòu)造方法對外不可見,該類的對象無法被創(chuàng)建。多用來實(shí)現(xiàn)單例模式。
在上面見了三種訪問修飾符,如果學(xué)過C++那么還知道一種沒有出現(xiàn)就是protected,本包中的子類可訪問,不同包中的子類可以訪問,不是子類不能訪問。
所以需要注意:在子類中使用父類的對象或者使用其類對象訪問父類的protected成員是不行的!
這里對包做一個(gè)解釋:包類似于電腦中的文件夾,文件多了需要存于不同文件夾中方便管理,同樣如此,類多了就需要放在不同的包里面方便管理。
關(guān)于被這四種修飾符修飾的屬性會(huì)方法的可訪問性做一個(gè)小結(jié):
范圍privatedefault(什么都不寫)protectedpublic
同一個(gè)類OOOO
同一個(gè)包中的子類XOOO
同一個(gè)包中的其他類XOXO
不同包中的子類XXOO
不同包中的非子類XXXO
構(gòu)造方法的調(diào)用時(shí)機(jī):
前面一直在說構(gòu)造方法的調(diào)用是在類創(chuàng)建時(shí),與普通方法不同,構(gòu)造方法在實(shí)例化新對象(使用new開辟空間后)調(diào)用一次。普通方法是在對象被實(shí)例化后可以調(diào)用多次。構(gòu)造方法也可以重載(重載的概念在后面介紹)。
我們可以跟蹤一下是如何調(diào)用類的構(gòu)造方法的。
以下面這個(gè)程序進(jìn)行跟蹤:
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("在使用傳進(jìn)來的pid賦值前:pid:"+this.pid);
? ? ? ? this.pid = pid;
? ? ? ? System.out.println("在使用傳進(jìn)來的pid賦值后:pid:"+this.pid);
? ? ? }
}
public class Student extends Person{? //extends 實(shí)現(xiàn)繼承關(guān)系
? private String name;
? private int age=0;
? public Student(){
? ? ? System.out.println("Student()");
? }
? public Student(long pid, String name, int age){
? ? super(pid);? ? ? ? //調(diào)用父類的構(gòu)造函數(shù)一定要寫在最前面不然會(huì)報(bào)錯(cuò)
? ? 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)
在使用傳進(jìn)來的pid賦值前:pid:123456789
在使用傳進(jìn)來的pid賦值后:pid:123456
Student(long pid, String name, int age)
*/在此我向大家推薦一個(gè)架構(gòu)學(xué)習(xí)交流裙。交流學(xué)習(xí)裙號:821169538,里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像?
可以輸出結(jié)果看出Java中的初始化順序如下:
在任何其他事情發(fā)生之前,會(huì)將分配給對象的存儲(chǔ)空間初始化成二進(jìn)制零。
調(diào)用基類的構(gòu)造函數(shù)。
按照聲明順序調(diào)用屬性的初始化方法。在Person中先將pid賦值為1234556789然后在返回到構(gòu)造函數(shù)中將123456賦值給pid。
調(diào)用導(dǎo)出類的構(gòu)造函數(shù)。若是Student中屬性有給定初始值,那么依舊如第三步后再進(jìn)入構(gòu)造函數(shù)進(jìn)行其他初始化操作。
什么是匿名對象以及匿名對象的基本使用
什么是匿名對象?
我們來看一步就創(chuàng)建對象的語法:
①類名稱 ②對象名稱 = ③new ④類名稱()
①:規(guī)定了對象的類型
②:對象的名字,唯一標(biāo)識對象
③:開辟新的堆內(nèi)存空間,存儲(chǔ)對象的內(nèi)容,若是沒有new,則沒有內(nèi)存空間,對象也就無法實(shí)例化
④:調(diào)用構(gòu)造方法初始化對象
④:在此我向大家推薦一個(gè)架構(gòu)學(xué)習(xí)交流裙。交流學(xué)習(xí)裙號:821169538,里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像?
上面的這條語句在內(nèi)存中開辟了兩個(gè)空間,一個(gè)??臻g存儲(chǔ)引用變量對象名稱,一個(gè)使用new開辟的堆空間用于存儲(chǔ)對象內(nèi)容。
對象名稱指向了在對堆中的對象,于是我們可以使用對象名稱去操作對象。

若是我們只有"new 類名稱();"這部分的話,那就是只是在堆中開辟了一個(gè)空間來保存對象信息,沒有棧去指向它。也就是這個(gè)空間是沒有名字的。
所以,沒有棧指向的對象就叫做匿名對象。
匿名對象的使用:
new Student(123456,"Sakura",20).getName();
由此就創(chuàng)建了一個(gè)匿名對象,可以向操作有名對象一樣操作它。
由于沒有引用變量指向匿名對象,所以只能使用一次,然后就會(huì)成為垃圾對象等待被GC回收,
小結(jié)
本篇博文主要總結(jié)了Java中構(gòu)造方法的定義和作用(為了在類對象實(shí)例化時(shí)設(shè)置屬性初始化)由此涉及到到類訪問權(quán)限,然后對類訪問權(quán)限做了一個(gè)小結(jié),以及Java程序初始化的順序。最后介紹了匿名對象,即沒有棧指向的對象。