java 聲明對(duì)象(轉(zhuǎn))
java 聲明對(duì)象(轉(zhuǎn))[@more@]正如剛才講過的,當(dāng)你創(chuàng)建一個(gè)類時(shí),你創(chuàng)建了一種新的數(shù)據(jù)類型。你可以使用這種類型來聲明該種類型的對(duì)象。然而,要獲得一個(gè)類的對(duì)象需要兩步。第一步,你必須聲明該類類型的一個(gè)變量,這個(gè)變量沒有定義一個(gè)對(duì)象。實(shí)際上,它只是一個(gè)能夠引用對(duì)象的簡(jiǎn)單變量。第二步,該聲明要?jiǎng)?chuàng)建一個(gè)對(duì)象的實(shí)際的物理拷貝,并把對(duì)于該對(duì)象的引用賦給該變量。這是通過使用new 運(yùn)算符實(shí)現(xiàn)的。new運(yùn)算符為對(duì)象動(dòng)態(tài)分配(即在運(yùn)行時(shí)分配)內(nèi)存空間,并返回對(duì)它的一個(gè)引用。這個(gè)引用或多或少的是new分配給對(duì)象的內(nèi)存地址。然后這個(gè)引用被存儲(chǔ)在該變量中。這樣,在Java 中,所有的類對(duì)象都必須動(dòng)態(tài)分配。讓我們?cè)敿?xì)看一下該過程。
在前面的例子中,用下面的語句來聲明一個(gè)Box類型的對(duì)象:
Box mybox = new Box();
本例將上面講到的兩步組合到了一起,可以將該語句改寫為下面的形式,以便將每一步講的更清楚:
Box mybox; // declare reference to object
mybox = new Box(); // allocate a Box object
第一行聲明了mybox ,把它作為對(duì)于Box類型的對(duì)象的引用。當(dāng)本句執(zhí)行后,mybox 包含的值為null ,表示它沒有引用對(duì)象。這時(shí)任何引用mybox 的嘗試都將導(dǎo)致一個(gè)編譯錯(cuò)誤。第二行創(chuàng)建了一個(gè)實(shí)際的對(duì)象,并把對(duì)于它的引用賦給mybox 。現(xiàn)在,你可以把mybox 作為Box的對(duì)象來使用。但實(shí)際上,mybox 僅僅保存實(shí)際的Box 對(duì)象的內(nèi)存地址。這兩行語句的效果如圖6-1 所示。
圖6-1 聲明Box 類型的對(duì)象
注意:那些熟悉C/C++ 語言的讀者,可能已經(jīng)注意到了對(duì)象的引用看起來和指針類似。這種懷疑實(shí)質(zhì)上是正確的。一個(gè)對(duì)象引用和內(nèi)存指針類似。主要的差別(也就是Java安全的關(guān)鍵)是你不能像實(shí)際的指針那樣來操作它。這樣,對(duì)于對(duì)象引用,你就不能像指針那樣任意分配內(nèi)存地址,或像整數(shù)一樣操作它。
6.2.1 深入研究new 運(yùn)算符
剛才已經(jīng)解釋過,new運(yùn)算符動(dòng)態(tài)地為一個(gè)對(duì)象分配地址。它的通用格式如下:
class-var = new classname( );
其中,class-var 是所創(chuàng)建類類型的變量。classname 是被實(shí)例化的類的名字。類的后面跟的圓括號(hào)指定了類的構(gòu)造函數(shù)。構(gòu)造函數(shù)定義當(dāng)創(chuàng)建一個(gè)類的對(duì)象時(shí)將發(fā)生什么。構(gòu)造函數(shù)是所有類的重要組成部分,并有許多重要的屬性。大多數(shù)類在他們自己的內(nèi)部顯式地定義構(gòu)造函數(shù)。如果一個(gè)類沒有顯式的定義它自己的構(gòu)造函數(shù),那么Java 將自動(dòng)地提供一個(gè)默認(rèn)的構(gòu)造函數(shù)。對(duì)類Box 的定義就是這種情況?,F(xiàn)在,我們將使用默認(rèn)的構(gòu)造函數(shù)。不久,你將看到如何定義自己的構(gòu)造函數(shù)。
這時(shí),你可能想知道為什么對(duì)整數(shù)或字符這樣的簡(jiǎn)單變量不使用new 運(yùn)算符。答案是Java 的簡(jiǎn)單類型不是作為對(duì)象實(shí)現(xiàn)的。出于效率的考慮,它們是作為“常規(guī)”變量實(shí)現(xiàn)的。你將看到,對(duì)象有許多特性和屬性,使Java 對(duì)對(duì)象的處理不同于簡(jiǎn)單類型。由于對(duì)處理對(duì)象和處理簡(jiǎn)單類型的開銷不同,Java 能更高效地實(shí)現(xiàn)簡(jiǎn)單類型。后面,你將看見,對(duì)于那些需要完全對(duì)象類型的情況下,簡(jiǎn)單類型的對(duì)象版本也是可用的。
理解new運(yùn)算符是在運(yùn)行期間為對(duì)象分配內(nèi)存的是很重要的。這樣做的好處是你的程序在運(yùn)行期間可以創(chuàng)建它所需要的內(nèi)存。但是,內(nèi)存是有限的,因此new有可能由于內(nèi)存不足而無法給一個(gè)對(duì)象分配內(nèi)存。如果出現(xiàn)這種情況,就會(huì)發(fā)生運(yùn)行時(shí)異常(你將在第10 章學(xué)習(xí)如何處理這種異常以及其他異常情況)。對(duì)于本書中的示例程序,你不必?fù)?dān)心內(nèi)存不足的情況,但是在實(shí)際的編程中你必須考慮這種可能性。
讓我們?cè)俅螐?fù)習(xí)類和對(duì)象之間的區(qū)別。類創(chuàng)建一種新的數(shù)據(jù)類型,該種類型能被用來創(chuàng)建對(duì)象。也就是,類創(chuàng)建了一個(gè)邏輯的框架,該框架定義了它的成員之間的關(guān)系。當(dāng)你聲明類的對(duì)象時(shí),你正在創(chuàng)造該類的實(shí)例。因此,類是一個(gè)邏輯構(gòu)造,對(duì)象有物理的真實(shí)性(也就是對(duì)象占用內(nèi)存空間)。弄清楚這個(gè)區(qū)別是很重要的。