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

創(chuàng)建句柄時恒序,我們希望它同一個新對象連接。通常用new關(guān)鍵字達到這一目的具帮。new的意思是:“把我變成這些對象的一種新類型”谭网。所以在上面的例子中汪厨,可以說:

String s = new String("asdf");

它不僅指出“將我變成一個新字串”,也通過提供一個初始字串愉择,指出了“如何生成這個新字串”劫乱。
當然,字串(String)并非唯一的類型锥涕。Java配套提供了數(shù)量眾多的現(xiàn)成類型衷戈。對我們來講,最重要的就是記住能自行創(chuàng)建類型层坠。事實上殖妇,這應(yīng)是Java程序設(shè)計的一項基本操作,是繼續(xù)本書后余部分學(xué)習(xí)的基礎(chǔ)窿春。

2.2.1 保存到什么地方

程序運行時拉一,我們最好對數(shù)據(jù)保存到什么地方做到心中有數(shù)。特別要注意的是內(nèi)存的分配旧乞。有六個地方都可以保存數(shù)據(jù):

(1) 寄存器。這是最快的保存區(qū)域磅氨,因為它位于和其他所有保存方式不同的地方:處理器內(nèi)部尺栖。然而,寄存器的數(shù)量十分有限烦租,所以寄存器是根據(jù)需要由編譯器分配延赌。我們對此沒有直接的控制權(quán),也不可能在自己的程序里找到寄存器存在的任何蹤跡叉橱。

(2) 堆棧挫以。駐留于常規(guī)RAM(隨機訪問存儲器)區(qū)域,但可通過它的“堆棧指針”獲得處理的直接支持窃祝。堆棧指針若向下移掐松,會創(chuàng)建新的內(nèi)存;若向上移粪小,則會釋放那些內(nèi)存大磺。這是一種特別快、特別有效的數(shù)據(jù)保存方式探膊,僅次于寄存器杠愧。創(chuàng)建程序時,Java編譯器必須準確地知道堆棧內(nèi)保存的所有數(shù)據(jù)的“長度”以及“存在時間”逞壁。這是由于它必須生成相應(yīng)的代碼流济,以便向上和向下移動指針锐锣。這一限制無疑影響了程序的靈活性,所以盡管有些Java數(shù)據(jù)要保存在堆棧里——特別是對象句柄绳瘟,但Java對象并不放到其中刺下。

(3) 堆。一種常規(guī)用途的內(nèi)存池(也在RAM區(qū)域)稽荧,其中保存了Java對象橘茉。和堆棧不同,“內(nèi)存堆”或“堆”(Heap)最吸引人的地方在于編譯器不必知道要從堆里分配多少存儲空間姨丈,也不必知道存儲的數(shù)據(jù)要在堆里停留多長的時間畅卓。因此,用堆保存數(shù)據(jù)時會得到更大的靈活性蟋恬。要求創(chuàng)建一個對象時翁潘,只需用new命令編制相關(guān)的代碼即可。執(zhí)行這些代碼時歼争,會在堆里自動進行數(shù)據(jù)的保存拜马。當然,為達到這種靈活性沐绒,必然會付出一定的代價:在堆里分配存儲空間時會花掉更長的時間俩莽!

(4) 靜態(tài)存儲。這兒的“靜態(tài)”(Static)是指“位于固定位置”(盡管也在RAM里)乔遮。程序運行期間扮超,靜態(tài)存儲的數(shù)據(jù)將隨時等候調(diào)用√0梗可用static關(guān)鍵字指出一個對象的特定元素是靜態(tài)的出刷。但Java對象本身永遠都不會置入靜態(tài)存儲空間。

(5) 常數(shù)存儲坯辩。常數(shù)值通常直接置于程序代碼內(nèi)部馁龟。這樣做是安全的,因為它們永遠都不會改變漆魔。有的常數(shù)需要嚴格地保護坷檩,所以可考慮將它們置入只讀存儲器(ROM)。

(6) 非RAM存儲有送。若數(shù)據(jù)完全獨立于一個程序之外淌喻,則程序不運行時仍可存在,并在程序的控制范圍之外雀摘。其中兩個最主要的例子便是“流式對象”和“固定對象”裸删。對于流式對象,對象會變成字節(jié)流阵赠,通常會發(fā)給另一臺機器涯塔。而對于固定對象肌稻,對象保存在磁盤中。即使程序中止運行匕荸,它們?nèi)钥杀3肿约旱臓顟B(tài)不變爹谭。對于這些類型的數(shù)據(jù)存儲,一個特別有用的技巧就是它們能存在于其他媒體中榛搔。一旦需要诺凡,甚至能將它們恢復(fù)成普通的、基于RAM的對象践惑。Java 1.1提供了對Lightweight persistence的支持腹泌。未來的版本甚至可能提供更完整的方案。

2.2.2 特殊情況:主要類型

有一系列類需特別對待尔觉;可將它們想象成“基本”凉袱、“主要”或者“主”(Primitive)類型,進行程序設(shè)計時要頻繁用到它們侦铜。之所以要特別對待专甩,是由于用new創(chuàng)建對象(特別是小的、簡單的變量)并不是非常有效钉稍,因為new將對象置于“堆”里涤躲。對于這些類型,Java采納了與C和C++相同的方法嫁盲。也就是說篓叶,不是用new創(chuàng)建變量,而是創(chuàng)建一個并非句柄的“自動”變量羞秤。這個變量容納了具體的值,并置于堆棧中左敌,能夠更高效地存取瘾蛋。

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

主類型 大小 最小值 最大值 封裝器類型
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ù)值類型全都是有符號(正負號)的,所以不必費勁尋找沒有符號的類型无宿。
主數(shù)據(jù)類型也擁有自己的“封裝器”(wrapper)類茵汰。這意味著假如想讓堆內(nèi)一個非主要對象表示那個主類型,就要使用對應(yīng)的封裝器孽鸡。例如:

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

也可以直接使用:

Character C = new Character('x');

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

1. 高精度數(shù)字

Java 1.1增加了兩個類栏豺,用于進行高精度的計算:BigInteger和BigDecimal。盡管它們大致可以劃分為“封裝器”類型豆胸,但兩者都沒有對應(yīng)的“主類型”奥洼。

這兩個類都有自己特殊的“方法”,對應(yīng)于我們針對主類型執(zhí)行的操作晚胡。也就是說灵奖,能對int或float做的事情,對BigInteger和BigDecimal一樣可以做估盘。只是必須使用方法調(diào)用瓷患,不能使用運算符。此外忿檩,由于牽涉更多尉尾,所以運算速度會慢一些。我們犧牲了速度燥透,但換來了精度沙咏。

BigInteger支持任意精度的整數(shù)。也就是說班套,我們可精確表示任意大小的整數(shù)值肢藐,同時在運算過程中不會丟失任何信息。
BigDecimal支持任意精度的定點數(shù)字吱韭。例如吆豹,可用它進行精確的幣值計算。

至于調(diào)用這兩個類時可選用的構(gòu)建器和方法理盆,請自行參考聯(lián)機幫助文檔痘煤。

2.2.3 Java的數(shù)組

幾乎所有程序設(shè)計語言都支持數(shù)組。在C和C++里使用數(shù)組是非常危險的猿规,因為那些數(shù)組只是內(nèi)存塊衷快。若程序訪問自己內(nèi)存塊以外的數(shù)組,或者在初始化之前使用內(nèi)存(屬于常規(guī)編程錯誤)姨俩,會產(chǎn)生不可預(yù)測的后果(注釋②)蘸拔。

②:在C++里,應(yīng)盡量不要使用數(shù)組环葵,換用標準模板庫(Standard TemplateLibrary)里更安全的容器调窍。

Java的一項主要設(shè)計目標就是安全性。所以在C和C++里困擾程序員的許多問題都未在Java里重復(fù)张遭。一個Java可以保證被初始化邓萨,而且不可在它的范圍之外訪問。由于系統(tǒng)自動進行范圍檢查,所以必然要付出一些代價:針對每個數(shù)組先誉,以及在運行期間對索引的校驗湿刽,都會造成少量的內(nèi)存開銷。但由此換回的是更高的安全性褐耳,以及更高的工作效率诈闺。為此付出少許代價是值得的。

創(chuàng)建對象數(shù)組時铃芦,實際創(chuàng)建的是一個句柄數(shù)組雅镊。而且每個句柄都會自動初始化成一個特殊值,并帶有自己的關(guān)鍵字:null(空)刃滓。一旦Java看到null仁烹,就知道該句柄并未指向一個對象。正式使用前咧虎,必須為每個句柄都分配一個對象卓缰。若試圖使用依然為null的一個句柄,就會在運行期報告問題砰诵。因此征唬,典型的數(shù)組錯誤在Java里就得到了避免。

也可以創(chuàng)建主類型數(shù)組茁彭。同樣地总寒,編譯器能夠擔保對它的初始化,因為會將那個數(shù)組的內(nèi)存劃分成零理肺。

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市妹萨,隨后出現(xiàn)的幾起案子年枕,更是在濱河造成了極大的恐慌,老刑警劉巖乎完,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件画切,死亡現(xiàn)場離奇詭異,居然都是意外死亡囱怕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門毫别,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娃弓,“玉大人,你說我怎么就攤上這事岛宦√ù裕” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長挽霉。 經(jīng)常有香客問我防嗡,道長,這世上最難降的妖魔是什么侠坎? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任蚁趁,我火速辦了婚禮,結(jié)果婚禮上实胸,老公的妹妹穿的比我還像新娘他嫡。我一直安慰自己,他們只是感情好庐完,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布钢属。 她就那樣靜靜地躺著,像睡著了一般门躯。 火紅的嫁衣襯著肌膚如雪淆党。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天讶凉,我揣著相機與錄音染乌,去河邊找鬼。 笑死缀遍,一個胖子當著我的面吹牛慕匠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播域醇,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼台谊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了譬挚?” 一聲冷哼從身側(cè)響起锅铅,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎减宣,沒想到半個月后盐须,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡漆腌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年贼邓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闷尿。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡塑径,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出填具,到底是詐尸還是另有隱情统舀,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站誉简,受9級特大地震影響碉就,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜闷串,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一瓮钥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧窿克,春花似錦骏庸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至只损,卻和暖如春一姿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背跃惫。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工叮叹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爆存。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓蛉顽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

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