麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Java中鮮為人知的缺點(diǎn)(上)

2019-11-18 13:28:19
字體:
供稿:網(wǎng)友

  java是當(dāng)今使用最廣泛的編程語言之一。自1995年發(fā)布以來,一直被用戶高度評(píng)價(jià)為“消除了C++缺點(diǎn)的優(yōu)秀編程語言”。不過,隨著它的廣泛使用,其缺點(diǎn)也在逐步地表現(xiàn)出來。
  
  Java的缺點(diǎn)公認(rèn)有如下三點(diǎn):(1)存在非對(duì)象的數(shù)據(jù)類型;(2)不能夠用一種描述方法來表達(dá)各種類(Class);(3)無法繼續(xù)2個(gè)以上的類的裝配。雖然也有人認(rèn)為編程語言應(yīng)該是一個(gè)什么樣子會(huì)因人而異,不應(yīng)該算成缺點(diǎn)。不過,上述三點(diǎn)卻可以導(dǎo)致編程人員使用混亂,降低源碼的可讀性及程序的可維護(hù)性。
  
  存在非對(duì)象的數(shù)據(jù)類型
   Java中鮮為人知的缺點(diǎn)(上)(圖一)


  表1●Java的原始類型(PRimitive)。原始類型包括表示真假的布爾型(Boolean)、字符型和數(shù)值型等(點(diǎn)擊放大)
  第一缺點(diǎn)是指雖說Java是面向?qū)ο蟮木幊陶Z言,但卻存在非對(duì)象的數(shù)據(jù)類型。
  
  “面向?qū)ο蟆钡亩x雖然有很多種,但無論何種定義,其最基本的概念都是利用包含數(shù)據(jù)和步驟的“對(duì)象”來表達(dá)系統(tǒng)。即便在Java領(lǐng)域,也會(huì)使用名為類的模型生成對(duì)象,并通過調(diào)用它的方法組織程序。
  
  但是,其中卻混雜著非對(duì)象的內(nèi)容。原始類型又被稱為基本數(shù)據(jù)類型(表1)。用于處理文字的char(字符型)、表示真假的boolean(布爾型)、int以及float等數(shù)值型就屬于這種數(shù)據(jù)類型。
  
  原始類型的內(nèi)存治理方法不同
   Java中鮮為人知的缺點(diǎn)(上)(圖二)
  圖1●Java的內(nèi)存治理方法。Java內(nèi)存區(qū)包括保存本地變量的內(nèi)存堆棧區(qū)(stack)和保存對(duì)象的數(shù)據(jù)的內(nèi)存堆區(qū)(heap)。堆棧區(qū)中存放的是用于引用(reference)對(duì)象時(shí)所需的信息(點(diǎn)擊放大)
  原始類型和對(duì)象型的內(nèi)存治理方法不同。Java虛擬機(jī)所治理的內(nèi)存區(qū)包括內(nèi)存堆棧區(qū)和內(nèi)存堆區(qū)(圖1)。內(nèi)存堆棧區(qū)用于存放本地變量的數(shù)據(jù)。按堆出的順序保存本地變量的數(shù)據(jù)。一旦脫離變量的有效范圍,該數(shù)據(jù)馬上就被釋放。
  
  而內(nèi)存堆區(qū)則用于存放對(duì)象本身。生成對(duì)象型的變量后,首先在內(nèi)存堆棧區(qū)中為其預(yù)備存放位置。然后利用new運(yùn)算符在這個(gè)位置生成新的對(duì)象后,對(duì)象及其數(shù)據(jù)就被存放到內(nèi)存堆區(qū)。接著,內(nèi)存堆區(qū)中的對(duì)象位置就會(huì)作為對(duì)象型的變量數(shù)據(jù)而被寫入內(nèi)存堆棧區(qū)。由于這些是引用對(duì)象時(shí)所用的信息,因此對(duì)象型變量被稱為“引用型”。
  
  而實(shí)際數(shù)據(jù)本身被寫入內(nèi)存堆棧區(qū)的是原始類型。采用這種內(nèi)存治理方法的類型稱為“數(shù)值型”。
  
  引用型變量改變以后,就會(huì)引用保存內(nèi)存堆區(qū)中的實(shí)際的對(duì)象數(shù)據(jù),重新改寫數(shù)據(jù)。比如,在方法的引數(shù)(arguments)中描述對(duì)象型變量時(shí)傳遞給方法的就是存放在這個(gè)位置中的信息。所以在方法內(nèi)追加的變更還會(huì)被反映到調(diào)用的原始對(duì)象上。另一方面,數(shù)值型變量傳遞的是它的值。即便在方法內(nèi)部進(jìn)行了變更,也不會(huì)反映到原始變量中。
  
  無法使用對(duì)象所具有的功能
  
  LIST 1●將數(shù)值數(shù)據(jù)保存在Java的矢量類中的程序。生成Integer類,然后封裝(Wrap)數(shù)值(點(diǎn)擊放大)
   Java中鮮為人知的缺點(diǎn)(上)(圖三)
點(diǎn)擊查看大圖

  LIST 1●將數(shù)值數(shù)據(jù)保存在Java的矢量類中的程序。生成Integer類,然后封裝(Wrap)數(shù)值(點(diǎn)擊放大)
  由于原始類型與對(duì)象型的內(nèi)存治理方法不同,因此就無法生成統(tǒng)一兩種數(shù)據(jù)的類庫。比如,假如只是對(duì)象型數(shù)據(jù)就能夠構(gòu)筑包含任意數(shù)據(jù)的類庫。
  
  可變長的數(shù)組類就是其中的一個(gè)例子。它是作為名為java.util.Vector的類而生成的。可以將任意的對(duì)象追加到數(shù)組中,還可以提取或刪除。能夠以此為引數(shù)指定任意的對(duì)象。但是,由于原始類型數(shù)據(jù)不是對(duì)象,因此無法直接引入。
  
  因此在Java中還存在相當(dāng)于原始類型的類。比如int型變量就可以使用java..lang.Integer類。重新生成Integer類,然后保存數(shù)據(jù),就可以追加到Vector矢量類中(LIST 1)。
  
  但是稍微想一想就會(huì)明白,這種方法并不是很靈活的做法。由于加入了多余的代碼,因此看起來感覺比較亂。而且還會(huì)浪費(fèi)內(nèi)存空間。原來的值暫且不說,還必須確保新建對(duì)象所需的內(nèi)存。不僅存在表面上的問題,還存在實(shí)質(zhì)上的問題。就是說無法保證數(shù)據(jù)的同一性。作為對(duì)象型保存的值與作為原始類型而保存的值完全不同。即便改變了原始類型的值,也不會(huì)反映到原來的int型數(shù)據(jù)。
  
  C#利用Boxing(裝箱)解決的只是一部分
  
  這一問題并非是Java特有的。比如,作為與Java類似的語言為用戶熟知的C#也存在相同的問題。C#利用稱為Boxing的方法部分地解決了這個(gè)問題。但是所解決的也只是可以不寫多余代碼的部分。內(nèi)存問題和同一性問題仍然存在。
  
  即便C#,int、double和char等數(shù)據(jù)類型也無法作為對(duì)象進(jìn)行處理。這些數(shù)據(jù)類型與Java的原始類型相同,也是數(shù)值型變量。
  
  C#可以將其值代入到對(duì)象中。LIST 2中顯示了具體的代碼。已經(jīng)將int型的值代入了對(duì)象型變量。此時(shí)先進(jìn)行裝箱,之后就開始靜靜地把基本數(shù)據(jù)類型的數(shù)據(jù)轉(zhuǎn)換成對(duì)象型數(shù)據(jù)。在內(nèi)存堆區(qū)中確保相應(yīng)的內(nèi)存,然后將數(shù)值型數(shù)據(jù)保存這里(圖2)。對(duì)象型變量引用的就是這些數(shù)據(jù)。
   Java中鮮為人知的缺點(diǎn)(上)(圖四)
點(diǎn)擊查看大圖

  LIST 2●執(zhí)行裝箱的C#代碼。將數(shù)值直接代入對(duì)象中。運(yùn)行代碼后,輸出0和1。也就是說變量a和o沒有同一性(點(diǎn)擊放大)
   Java中鮮為人知的缺點(diǎn)(上)(圖五)
  圖2●C#中的裝箱法。對(duì)存放于內(nèi)存堆棧區(qū)中的int型結(jié)構(gòu)體(strUCts)裝箱時(shí),就會(huì)靜靜地在內(nèi)存堆區(qū)中生成對(duì)象。因此就無法確保與初始值的匹配性。(點(diǎn)擊放大)
  筆者利用裝箱法,用C#試著寫了一段與在Java的Vector矢量類中保存數(shù)值類似的代碼(LIST 3)。雖然ArrayList類要引數(shù)中提取對(duì)象型變量,但這里由于通過直接int型變量,因此代碼非常整潔。
  
  不過,并沒有解決多余的內(nèi)存消耗和數(shù)值的同一性問題。因?yàn)橹皇菃渭兊貙?shí)現(xiàn)了自動(dòng)向?qū)ο蟮霓D(zhuǎn)換(圖3)。
   Java中鮮為人知的缺點(diǎn)(上)(圖六)
  LIST 3●與LIST 1起相同作用的C#代碼。由于具有裝箱法,因此可以直接向ArrayList中追加數(shù)值
  Java中鮮為人知的缺點(diǎn)(上)(圖七)
點(diǎn)擊查看大圖

  圖3●利用Java和C#,將int型變量轉(zhuǎn)換成對(duì)象的方法。盡管內(nèi)部處理基本相同,但C#的特點(diǎn)是隱式轉(zhuǎn)換
  假如考慮到實(shí)用,也算得上是優(yōu)點(diǎn)
  
  從上述所講來看,就會(huì)生出這樣的疑問:為什么最新的Java和C#語言還存在著這樣的問題呢?實(shí)際上這是因?yàn)閷?duì)其性能的重視。
  
  由于原始數(shù)據(jù)型數(shù)據(jù)在編程時(shí)使用得最多,因此利用能夠?qū)ζ溥M(jìn)行快速處理的原始類型,性能就會(huì)提高。而對(duì)象型數(shù)據(jù)在生成對(duì)象,以及使用位置信息去引用內(nèi)存堆區(qū)中的數(shù)據(jù)時(shí)則會(huì)產(chǎn)生一定的開銷。另一個(gè)問題是內(nèi)存堆區(qū)。假如全部是對(duì)象型,比如,只要執(zhí)行簡單的for循環(huán)語句,就會(huì)在內(nèi)存堆區(qū)中生成大量的對(duì)象。由于內(nèi)存堆區(qū)的消耗速度就會(huì)急劇上升,并且頻繁地進(jìn)行資源回收處理,因此性能就會(huì)降低。
  
  Java和C#是考慮到性能問題才生成原始數(shù)據(jù)型數(shù)據(jù)的。因此并不能說是“純粹的”面向?qū)ο笳Z言。也許可以說是考慮到實(shí)用性的穩(wěn)妥做法吧。(記者:大森 敏行、八木 玲子)

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产成人综合在线视频 | 国产成人在线免费观看视频 | 午夜视频久久 | 国产精品99久久久久久大便 | 国产精品av久久久久久久久久 | 男女做性免费网站 | 免费看黄色一级大片 | 午夜影院在线免费观看 | 黄色99视频 | 鲁人人人鲁人人鲁精品 | 久久99久久98精品免观看软件 | 欧美 亚洲 激情 | 欧美成年性h版影视中文字幕 | 国产 日韩 亚洲 欧美 | 法国极品成人h版 | 成年人黄视频 | 久久性生活免费视频 | 免费国产一级特黄久久 | 亚洲午夜影院在线观看 | 性欧美大战久久久久久久免费观看 | 斗破苍穹在线观看免费完整观看 | 97伦理| 黄色一级片免费观看 | 男女一边摸一边做羞羞视频免费 | 一级大片一级一大片 | 午夜国内精品a一区二区桃色 | 中文字幕在线观看1 | 欧美熟videos肥婆 | 国产女同疯狂激烈互摸 | 私库av在线免费观看 | 九九热精品在线视频 | 一级做a爱片性色毛片高清 国产精品色在线网站 | 欧美激情综合在线 | av在线免费看片 | 成人国产精品久久久 | 黄色羞羞视频在线观看 | 男女视频免费看 | 日本a∨精品中文字幕在线 欧美1—12sexvideos | 99热草| 久久久久久久久久网 | 亚洲午夜1000理论片aa |