2.2 所有對(duì)象都必須創(chuàng)建

2.2 所有對(duì)象都必須創(chuàng)建

創(chuàng)建句柄時(shí)禽最,我們希望它同一個(gè)新對(duì)象連接。通常用new關(guān)鍵字達(dá)到這一目的呛占。new的意思是:“把我變成這些對(duì)象的一種新類型”懦趋。所以在上面的例子中,可以說:

String s = new String("asdf");

它不僅指出“將我變成一個(gè)新字串”帜篇,也通過提供一個(gè)初始字串诫咱,指出了“如何生成這個(gè)新字串”。
當(dāng)然坎缭,字串(String)并非唯一的類型签钩。Java配套提供了數(shù)量眾多的現(xiàn)成類型凯亮。對(duì)我們來講,最重要的就是記住能自行創(chuàng)建類型假消。事實(shí)上,這應(yīng)是Java程序設(shè)計(jì)的一項(xiàng)基本操作臼予,是繼續(xù)本書后余部分學(xué)習(xí)的基礎(chǔ)啃沪。

2.2.1 保存到什么地方

程序運(yùn)行時(shí),我們最好對(duì)數(shù)據(jù)保存到什么地方做到心中有數(shù)创千。特別要注意的是內(nèi)存的分配追驴。有六個(gè)地方都可以保存數(shù)據(jù):

(1) 寄存器。這是最快的保存區(qū)域殿雪,因?yàn)樗挥诤推渌斜4娣绞讲煌牡胤剑禾幚砥鲀?nèi)部。然而爸业,寄存器的數(shù)量十分有限亏镰,所以寄存器是根據(jù)需要由編譯器分配。我們對(duì)此沒有直接的控制權(quán)薄霜,也不可能在自己的程序里找到寄存器存在的任何蹤跡纸兔。

(2) 堆棧。駐留于常規(guī)RAM(隨機(jī)訪問存儲(chǔ)器)區(qū)域汉矿,但可通過它的“堆棧指針”獲得處理的直接支持洲拇。堆棧指針若向下移曲尸,會(huì)創(chuàng)建新的內(nèi)存男翰;若向上移,則會(huì)釋放那些內(nèi)存蛾绎。這是一種特別快、特別有效的數(shù)據(jù)保存方式鹏倘,僅次于寄存器顽爹。創(chuàng)建程序時(shí),Java編譯器必須準(zhǔn)確地知道堆棧內(nèi)保存的所有數(shù)據(jù)的“長(zhǎng)度”以及“存在時(shí)間”捏题。這是由于它必須生成相應(yīng)的代碼肉渴,以便向上和向下移動(dòng)指針。這一限制無疑影響了程序的靈活性,所以盡管有些Java數(shù)據(jù)要保存在堆棧里——特別是對(duì)象句柄庸诱,但Java對(duì)象并不放到其中。

(3) 堆朱灿。一種常規(guī)用途的內(nèi)存池(也在RAM區(qū)域)钠四,其中保存了Java對(duì)象。和堆棧不同侣灶,“內(nèi)存堆”或“堆”(Heap)最吸引人的地方在于編譯器不必知道要從堆里分配多少存儲(chǔ)空間缕碎,也不必知道存儲(chǔ)的數(shù)據(jù)要在堆里停留多長(zhǎng)的時(shí)間。因此凡怎,用堆保存數(shù)據(jù)時(shí)會(huì)得到更大的靈活性。要求創(chuàng)建一個(gè)對(duì)象時(shí)统倒,只需用new命令編制相關(guān)的代碼即可。執(zhí)行這些代碼時(shí)耸成,會(huì)在堆里自動(dòng)進(jìn)行數(shù)據(jù)的保存坛缕。當(dāng)然,為達(dá)到這種靈活性毙沾,必然會(huì)付出一定的代價(jià):在堆里分配存儲(chǔ)空間時(shí)會(huì)花掉更長(zhǎng)的時(shí)間宠页!

(4) 靜態(tài)存儲(chǔ)。這兒的“靜態(tài)”(Static)是指“位于固定位置”(盡管也在RAM里)烤宙。程序運(yùn)行期間俭嘁,靜態(tài)存儲(chǔ)的數(shù)據(jù)將隨時(shí)等候調(diào)用」赵疲可用static關(guān)鍵字指出一個(gè)對(duì)象的特定元素是靜態(tài)的近她。但Java對(duì)象本身永遠(yuǎn)都不會(huì)置入靜態(tài)存儲(chǔ)空間。

(5) 常數(shù)存儲(chǔ)粘捎。常數(shù)值通常直接置于程序代碼內(nèi)部。這樣做是安全的泳桦,因?yàn)樗鼈冇肋h(yuǎn)都不會(huì)改變娩缰。有的常數(shù)需要嚴(yán)格地保護(hù),所以可考慮將它們置入只讀存儲(chǔ)器(ROM)梧奢。

(6) 非RAM存儲(chǔ)。若數(shù)據(jù)完全獨(dú)立于一個(gè)程序之外趋惨,則程序不運(yùn)行時(shí)仍可存在惦蚊,并在程序的控制范圍之外。其中兩個(gè)最主要的例子便是“流式對(duì)象”和“固定對(duì)象”蹦锋。對(duì)于流式對(duì)象莉掂,對(duì)象會(huì)變成字節(jié)流,通常會(huì)發(fā)給另一臺(tái)機(jī)器憎妙。而對(duì)于固定對(duì)象,對(duì)象保存在磁盤中褥符。即使程序中止運(yùn)行抚垃,它們?nèi)钥杀3肿约旱臓顟B(tài)不變。對(duì)于這些類型的數(shù)據(jù)存儲(chǔ)铣焊,一個(gè)特別有用的技巧就是它們能存在于其他媒體中魂迄。一旦需要惋耙,甚至能將它們恢復(fù)成普通的、基于RAM的對(duì)象湿酸。Java 1.1提供了對(duì)Lightweight persistence的支持灭美。未來的版本甚至可能提供更完整的方案仇穗。

2.2.2 特殊情況:主要類型

有一系列類需特別對(duì)待昵观;可將它們想象成“基本”、“主要”或者“主”(Primitive)類型扩所,進(jìn)行程序設(shè)計(jì)時(shí)要頻繁用到它們祖屏。之所以要特別對(duì)待买羞,是由于用new創(chuàng)建對(duì)象(特別是小的、簡(jiǎn)單的變量)并不是非常有效期丰,因?yàn)閚ew將對(duì)象置于“堆”里漠嵌。對(duì)于這些類型,Java采納了與C和C++相同的方法儒鹿。也就是說约炎,不是用new創(chuàng)建變量,而是創(chuàng)建一個(gè)并非句柄的“自動(dòng)”變量圾浅。這個(gè)變量容納了具體的值,并置于堆棧中喷鸽,能夠更高效地存取灸拍。

Java決定了每種主要類型的大小。就象在大多數(shù)語言里那樣混槐,這些大小并不隨著機(jī)器結(jié)構(gòu)的變化而變化轩性。這種大小的不可更改正是Java程序具有很強(qiáng)移植能力的原因之一。

主類型 大小 最小值 最大值 封裝器類型
boolean 1-bit Boolean
char 16-bit Unicode 0 Unicode 216- 1 Character
byte 8-bit -128 +127 Byte[11]
short 16-bit -215 +215 – 1 Short1
int 32-bit -231 +231 – 1 Integer
long 64-bit -263 +263 – 1 Long
float 32-bit IEEE754 IEEE754 Float
double 64-bit IEEE754 IEEE754 Double
void Void1

①:到Java 1.1才有悯嗓,1.0版沒有脯厨。

數(shù)值類型全都是有符號(hào)(正負(fù)號(hào))的,所以不必費(fèi)勁尋找沒有符號(hào)的類型俄认。
主數(shù)據(jù)類型也擁有自己的“封裝器”(wrapper)類眯杏。這意味著假如想讓堆內(nèi)一個(gè)非主要對(duì)象表示那個(gè)主類型,就要使用對(duì)應(yīng)的封裝器岂贩。例如:

char c = 'x';
Character C = new Character('c');

也可以直接使用:

Character C = new Character('x');

這樣做的原因?qū)⒃谝院蟮恼鹿?jié)里解釋萎津。

1. 高精度數(shù)字

Java 1.1增加了兩個(gè)類,用于進(jìn)行高精度的計(jì)算:BigInteger和BigDecimal锉屈。盡管它們大致可以劃分為“封裝器”類型,但兩者都沒有對(duì)應(yīng)的“主類型”遂黍。

這兩個(gè)類都有自己特殊的“方法”俊嗽,對(duì)應(yīng)于我們針對(duì)主類型執(zhí)行的操作。也就是說芯咧,能對(duì)int或float做的事情竹揍,對(duì)BigInteger和BigDecimal一樣可以做。只是必須使用方法調(diào)用驶拱,不能使用運(yùn)算符晶衷。此外,由于牽涉更多税迷,所以運(yùn)算速度會(huì)慢一些锹漱。我們犧牲了速度,但換來了精度毕泌。

BigInteger支持任意精度的整數(shù)嗅辣。也就是說,我們可精確表示任意大小的整數(shù)值愿题,同時(shí)在運(yùn)算過程中不會(huì)丟失任何信息蛙奖。
BigDecimal支持任意精度的定點(diǎn)數(shù)字。例如仔夺,可用它進(jìn)行精確的幣值計(jì)算攒砖。

至于調(diào)用這兩個(gè)類時(shí)可選用的構(gòu)建器和方法,請(qǐng)自行參考聯(lián)機(jī)幫助文檔灶体。

2.2.3 Java的數(shù)組

幾乎所有程序設(shè)計(jì)語言都支持?jǐn)?shù)組掐暮。在C和C++里使用數(shù)組是非常危險(xiǎn)的,因?yàn)槟切?shù)組只是內(nèi)存塊樟结。若程序訪問自己內(nèi)存塊以外的數(shù)組精算,或者在初始化之前使用內(nèi)存(屬于常規(guī)編程錯(cuò)誤),會(huì)產(chǎn)生不可預(yù)測(cè)的后果(注釋②)驮履。

②:在C++里,應(yīng)盡量不要使用數(shù)組倒戏,換用標(biāo)準(zhǔn)模板庫(Standard TemplateLibrary)里更安全的容器恐似。

Java的一項(xiàng)主要設(shè)計(jì)目標(biāo)就是安全性。所以在C和C++里困擾程序員的許多問題都未在Java里重復(fù)葛闷。一個(gè)Java可以保證被初始化双藕,而且不可在它的范圍之外訪問。由于系統(tǒng)自動(dòng)進(jìn)行范圍檢查蔓彩,所以必然要付出一些代價(jià):針對(duì)每個(gè)數(shù)組赤嚼,以及在運(yùn)行期間對(duì)索引的校驗(yàn),都會(huì)造成少量的內(nèi)存開銷更卒。但由此換回的是更高的安全性蹂空,以及更高的工作效率。為此付出少許代價(jià)是值得的上枕。

創(chuàng)建對(duì)象數(shù)組時(shí)辨萍,實(shí)際創(chuàng)建的是一個(gè)句柄數(shù)組。而且每個(gè)句柄都會(huì)自動(dòng)初始化成一個(gè)特殊值爪飘,并帶有自己的關(guān)鍵字:null(空)拉背。一旦Java看到null,就知道該句柄并未指向一個(gè)對(duì)象犁罩。正式使用前,必須為每個(gè)句柄都分配一個(gè)對(duì)象昼汗。若試圖使用依然為null的一個(gè)句柄顷窒,就會(huì)在運(yùn)行期報(bào)告問題源哩。因此,典型的數(shù)組錯(cuò)誤在Java里就得到了避免谓着。

也可以創(chuàng)建主類型數(shù)組坛掠。同樣地,編譯器能夠擔(dān)保對(duì)它的初始化舷蒲,因?yàn)闀?huì)將那個(gè)數(shù)組的內(nèi)存劃分成零友多。

數(shù)組問題將在以后的章節(jié)里詳細(xì)討論。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纵柿,一起剝皮案震驚了整個(gè)濱河市昂儒,隨后出現(xiàn)的幾起案子委可,更是在濱河造成了極大的恐慌,老刑警劉巖刹枉,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屈呕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蟋软,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來湿痢,“玉大人譬重,你說我怎么就攤上這事⊥喂妫” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谨究。 經(jīng)常有香客問我,道長(zhǎng)憎蛤,這世上最難降的妖魔是什么纪吮? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任碾盟,我火速辦了婚禮,結(jié)果婚禮上屈藐,老公的妹妹穿的比我還像新娘熙尉。我一直安慰自己,他們只是感情好包归,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布铅歼。 她就那樣靜靜地躺著,像睡著了一般厦幅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上译荞,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天磁椒,我揣著相機(jī)與錄音玫芦,去河邊找鬼本辐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛老虫,可吹牛的內(nèi)容都是我干的茫多。 我是一名探鬼主播祈匙,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼天揖!你這毒婦竟也來了夺欲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤今膊,失蹤者是張志新(化名)和其女友劉穎些阅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斑唬,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡市埋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恕刘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡褐着,死狀恐怖弓千,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情献起,我是刑警寧澤洋访,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布镣陕,位于F島的核電站,受9級(jí)特大地震影響姻政,放射性物質(zhì)發(fā)生泄漏呆抑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一汁展、第九天 我趴在偏房一處隱蔽的房頂上張望鹊碍。 院中可真熱鬧,春花似錦食绿、人聲如沸侈咕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耀销。三九已至,卻和暖如春铲汪,著一層夾襖步出監(jiān)牢的瞬間熊尉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工掌腰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狰住,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓齿梁,卻偏偏與公主長(zhǎng)得像催植,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子勺择,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 創(chuàng)建句柄時(shí)创南,我們希望它同一個(gè)新對(duì)象連接。通常用new關(guān)鍵字達(dá)到這一目的酵幕。new的意思是:“把我變成這些對(duì)象的一種新...
    old程序猿閱讀 230評(píng)論 0 0
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,103評(píng)論 1 32
  • 前言 不知道大家有沒有這樣一種感覺芳撒,程序員的數(shù)量井噴了邓深。可能是因?yàn)榛ヂ?lián)網(wǎng)火了笔刹,也可能是各家培訓(xùn)機(jī)構(gòu)為我們拉來了大量...
    活這么大就沒飽過閱讀 2,727評(píng)論 6 26
  • 在一個(gè)方法內(nèi)部定義的變量都存儲(chǔ)在棧中芥备,當(dāng)這個(gè)函數(shù)運(yùn)行結(jié)束后,其對(duì)應(yīng)的棧就會(huì)被回收舌菜,此時(shí)萌壳,在其方法體中定義的變量將不...
    Y了個(gè)J閱讀 4,418評(píng)論 1 14
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理,因此不免有一些不準(zhǔn)確的地方,同時(shí)不同JDK版本的...
    高廣超閱讀 15,604評(píng)論 3 83