CLDC
CLDC |
中文名: 有限連接設備配置 外文名: CLDC (Connected Limited Device Configuration) 版 本: 1.0和1.1兩個版本 支 持: profile |
CLDC (Connected Limited Device Configuration,有限連接設備配置) 是為運行在資源非常有限的設備(例如尋呼機或者手機)上的J2ME應用程序制訂的架構。規範內容包括目標機器的特性、虛擬機規範和基本的API等等。 有1.0和1.1兩個版本。[1]
目錄
發展
CLDC是由包括Nokia,Motorola和Siemens在內的18 家全球知名公司共同協 商完成的。 CLDC 的核心是虛擬機和核心類庫。虛擬機運行在目標操作系統之上,對下層的硬件提供必要的兼容和支持;核心類庫提供操作系統所需的最小的軟件需求。 2000年5月,Java Community Process(JCP)公布了CLDC1.0規範(即JSR30)。CLDC是J2ME核心配置中的一個,可以支持一個或多個profile。其目標主要面向小型的、網絡連接速度慢、能源有限(主要是電池供電)且資源有限的設備,如手機、機頂盒、PDA等。CLDC1.0的規範可以在jcp的網站上下載。
目標
1) 為小型的、資源受限的連接設備定義一個Java 平台標準 2) 允許向上述設備動態的傳遞Java 應用和內容 3) 使Java 開發人員能夠輕鬆的在這些設備上進行應用開發
整體需求
1) 能運行在絕大多數的小型的、資源受限的連接設備上 2) 用CLDC 為上述設備開發的應用儘可能的不使用設備的本地系統軟件(做到與平台、設備無關) 3) 定義能應用在絕大多數上述設備上的最小子集的規範 4) 保證在不同類型上述設備之間代碼級的可移植性和互操作性 1. CLDC 的硬件需求 由於CLDC 要面向儘可能多的設備,而這些設備所使用的硬件又各不相同。因此CLDC 規範中並沒有指明需要某種硬件支持,只是對設備的最小內存進行了限制。CLDC 規範中要求硬件必須達到以下要求: 1) 至少160KB 的固定內存以供虛擬機和CLDC 核心類庫使用。 2) 至少32KB 的動態內存以供虛擬機運行時使用(堆棧等)。 這裡所說的固定內存是指擁有寫保護,不會因關機而抹去的ROM。對於具體的設備的具體實現,這些需求也可能有變化。這裡所規定的160KB 是CLDC 規範中的要求,實際也可以是128KB 左右。 2. CLDC 的軟件需求 和硬件類似,CLDC 上運行的軟件也是多種多樣的。例如,有些設備支持多進程操作系統或者支持文件系統;而有些功能極其有限的設備並不需要文件系統。對於這些不確定性,CLDC只定義了軟件所必須的最小集合。CLDC 規範中要求操作系統不需要支持多進程或是分址空間尋址,也不用考慮運行時的協調和延遲;但是必須提供至少一個可控制的實體來運行虛擬機。
功能範圍
4.1 CLDC包含的功能在CLDC1.0版本中定義了以下功能: 1)Java核心語言與Java虛擬機的特性 2)核心Java類庫 3)輸入/輸出 4)對網絡的支持 5)對安全性的支持 6)對國際化的支持 4.2 CLDC不包含的功能1)對應用程序生命周期的管理 2)用戶界面 3)事件處理 4)高級應用程序模式(這裡指用戶與應用程序的交互) 4.3 CLDC與J2SE的關係 CLDC包含了一個基本的J2ME運行環境,其中包括虛擬機和核心的java類庫。作為專門針對於小型設備的配置,CLDC對J2SE類庫進行了大量的簡化,其類庫只保留了java 規範中定義的最核心的3個包,即java.iojava.lang和java.util,並重新定義了一個新的包javax.microedition。這裡你可以通過前綴來區別:java.表示核心的java包,javax.表示標準java擴展包。 這裡要注意的是在CLDC中定義的javax.microedition包為javax.microedition. io,用來支持通用連接框架(GCF,Generic connection framework)。CLDC中的包和所對應的功能如下所示: 1) CLDC包 2) 對應的功能 1) java.io 2) 標準的輸入/輸出功能,J2SE java.io包的子集 3) java.lang 4) 核心語言包,J2SE的子集 5) java.util 6) 實用類 7) javax.microedition. io 8) 通用連接框架類及接口 CLDC中的包和所對應的功能 javax.microedition中其他的包定義了CLDC中沒有定義的功能,如對應用程序生命周期的管理、用戶界面(UI)、事件處理模式、永久性存儲和用戶與應用程序的交互等。這些功能的定義是由Profile (即MIDP)來完成的。 4.4 CLDC核心類庫與J2SE的主要區別 由於CLDC主要針對16位、32位主頻在16MHz以上的處理器,設備內存只有512KB,甚至更少,而目前Windows平台下運行的JVM需要的最小內存為16M。因此CLDC所使用的虛擬機和核心類庫與J2SE的並不相同。 1.不支持浮點數據類型(沒有float和double) 因為很多使用CLDC的設備硬件都不支持浮點運算,而且處理浮點運算需要較大的內存。因此在CLDC1.0中,並沒有要求虛擬機支持浮點數據類型。 9) dadd 10) dmul 11) fadd 12) fmul 13) i2d 14) dalaod 15) dneg 16) faload 17) fneg 18) i2f 19) dastore 20) drem 21) fastore 22) frem 23) l2d 24) dcmpg 25) dreturn 26) fcmpg 27) freturn 28) l2f 29) dcmpl 30) dstore 31) fcmpl 32) fstore 33) newarray(double) 34) dconst_0 35) dstore_x 36) fconst_0 37) fstore_x 38) newarray(float) 39) dconst_1 40) dsub 41) fconst_1 42) fsub 43) 44) ddiv 45) d2f 46) fdiv 47) f2f 48) 49) dload 50) d2i 51) fload 52) f2i 53) 54) dload_x 55) d2l 56) fload_x 57) f2l 58) CLDC不支持的浮點數據類型 對於CLDC的應用,Sun使用了和J2SE相同的編譯器,這使得使用浮點數據的類及對象在編譯的時候可以正常通過。因此Sun引入了類審核機制來阻止未經定義的類調入虛擬機。 2.不支持JNI (the Java Native Interface ) CLDC不提供native code的支持,除了因為設備內存有限外,還出於安全性的考慮。因為CLDC中缺少完整的安全性模型,禁用了這些J2SE的特性可以使潛在的安全風險降到最低。 3.不支持以及用戶自定義的Java級的類載入器(class loaders) CLDC不允許用戶自定義類載入器。按照CLDC規範的要求,類的載入是不能被覆蓋、替換和修改的。和JNI類似,這些是出於安全方面的一些考慮。 4.不支持反射(reflection) 不支持java.lang.reflect包以及java.lang.Class中和reflection有關的函數。其目的主要是節省內存占用。 5.不支持線程組(thread groups)或守護線程(daemon threads) CLDC提供了對線程的支持,也支持多線程,但是線程組和守護線程是不被允許的。每個線程都要生成獨立??程的操作,則必須在應用程序的級別上自行實現多個Thread對象的控制,如使用Hashtable和Vector來存取多個Thread對象。 6.不支持類實例(class instance)的終結(finalization) CLDC類庫不包含java.lang.Object.finalize()方法,因此類對象的終結是不支持的。對於應用CLDC的設備來說,對象終結相對於它所起的作用來說實現起來過於複雜,並不被需要。 7.不支持弱引用(weak references) 8.有限的錯誤處理(error handling) 在J2SE中定義了大量的類用來描述各種錯誤和異常,而CLDC僅僅包含有限的幾個J2SE的核心類庫,因此大部分java.lang.Error的子類都未被支持,這包括異步異常。這是因為在嵌入式系統中,應用程序並不期望獲得設備的出錯處理機制;定義和運行出錯處理需要較大的虛擬機的開銷,而這些出錯的代碼信息對於連用戶界面都沒有的有限連接設備來說是沒有用處的。
新特性
CLDC1.1即JSR139相對於1.0版本並沒有本質上的變化。隨着硬件水平的不斷提高,CLDC1.1在兼容性和可用性上作了一些改進,並增加了一些1.0版本沒有的新特性: 1. 增加對浮點數據的支持 2. 核心類庫中增加java.lang.Float類和java.lang.Double類 3. 部分支持弱參考(weak references) 4. Calendar、Date和TimeZone類被重新設計 5. 與J2SE中的類更加類似 6. 對錯誤處理有了更加明確的定義 7. 並增加了 NoClassDefFoundError 類 8. 對於Thread類 9. CLDC1.1允許為線程命名 10. 並通過getName() 方法得知線程的名字 11. 增加interrupt()方法 12. 允許中斷線程;增加了新的構造方法。 13. 對一些類庫進行了小的修改 14. 以下的方法被添加或是修正: Boolean.TRUE and Boolean.FALSE Date.toString() Random.nextInt(int n) String.intern() String.equalsIgnoreCase() 15. 由於允許使用浮點運算 16. 設備的最小內存被提高到160 至 192 KB 下面列出CLDC1.1增加的類和方法: l 增加java.lang.Float和java.lang.Double類 l 增加以下和浮點數據相關的方法 java.lang.Integer.doubleValue() java.lang.Integer.floatValue() java.lang.Long.doubleValue() java.lang.Long.floatValue() java.lang.Math.abs(double a) java.lang.Math.abs(float a) java.lang.Math.max(double a, double b) java.lang.Math.max(float a, float b) java.lang.Math.min(double a, double b) java.lang.Math.min(float a, float b) java.lang.Math.ceil(double a) java.lang.Math.floor(double a) java.lang.Math.sin(double a) java.lang.Math.cos(double a) java.lang.Math.tan(double a) java.lang.Math.sqrt(double a) java.lang.Math.toDegrees(double angrad) java.lang.Math.toRadians(double angrad) java.lang.String.valueOf(double d) java.lang.String.valueOf(float f) java.lang.StringBuffer.append(double d) java.lang.StringBuffer.append(float f) java.lang.StringBuffer.insert(int offset, double d) java.lang.StringBuffer.insert(int offset, float f) java.io.DataInput.readDouble() java.io.DataInput.readFloat() java.io.DataInputStream.readDouble() java.io.DataInputStream.readFloat() java.io.DataOutput.writeDouble(double v) java.io.DataOutput.writeFloat(float v) java.io.DataOutputStream.writeDouble(double v) java.io.DataOutputStream.writeFloat(float f) java.io.PrintStream.print(double d) java.io.PrintStream.print(float f) java.io.PrintStream.println(double d) java.io.PrintStream.println(float f) java.util.Random.nextDouble() java.util.Random.nextFloat() l 增加浮點計算常量е和圓周率π: java.lang.Math.E java.lang.Math.PI l 增加弱參考類java.lang.ref.Reference和java.lang.ref.WeakReference。 l 新增錯誤類NoClassDefFoundError。 l 增加Thread類的構造函數及方法: Thread.getName() Thread.interrupt() Thread(Runnable Target, String name) Thread(String name) l 新增的一些常數及方法: java.lang.Boolean.TRUE and java.lang.Boolean.FALSE java.lang.String.intern() java.lang.String.equalsIgnoreCase() java.util.Date.toString() java.util.Random.nextInt(int n) 要查看CLDC1.1更詳細的變化可以去Sun的網站下載CLDC1.1的規範
安全機制
5.1 CLDC的安全級別 在CLDC中,虛擬機不允許用戶安裝程序,因此安全特性和J2SE比要少很多。CLDC規範中主要定義了以下3個級別的安全機制: 1,底層安全機制(low-level security) 底層安全就是通常說的虛擬機的安全,是虛擬機運行在CLDC設備上的最關鍵的安全機制。它要求運行在虛擬機上的應用程序必須遵循Java語言的標準語法,且能夠檢查出並組織惡意代碼(類)以各種方式對設備進行破壞。對於標準的Java虛擬機的實現,虛擬機使用類審核的方式來保證虛擬機安全。類審核機制能夠確保類文件中的字節碼以及其他對象不包含非法指令,不會以非法的順序被執行,也不會訪問虛擬機以外的非法內存地址或是地址段。 在CLDC中,類的審核機制不同於J2SE,它增加了預審核(pre-verification)機制。2.3.1節將對CLDC的預審核機製做詳細的說明。 2,應用級別安全機制(application-level security) 僅用類審核機制來保證Java平台的安全運行是不夠的。因為它僅僅能夠確保應用程序的代碼是可用的,還有很多潛在的安全威脅沒有被涉及到,如對文件系統、打印設備、紅外、本地類庫以及網絡等安全管理。在應用級別安全機制中,CLDC規定,Java應用程序只能訪問系統類庫、系統資源、額外的設備元件(如即插即用的設備等)和Java運行環境。 具體的實現是:應用程序運行在一個封閉的沙箱(sandbox)環境中以得到保護。在沙箱中,只有系統已定義的配置(configuration)、簡表(profile)、可選包以及設備支持的一些類可以被應用程序訪問。任何沒有預先定義類庫和資源都不允許訪問,以防程序中的惡意代碼對沙箱外的資源(如操作系統、硬盤等)非法訪問或者破壞。 沙箱的需求主要有: l 類文件必須經過審核且是可用的Java程序。 l 應用程序的下載、安裝和管理等操作都不能修改、覆蓋或着繞過類虛擬機實現的標準的加載機制。 l 只有預先定義好的,封閉的Java API和類可以被應用程序調用。這包括配置、簡表、可選包以及該應用自定義的類。 l 任何沒有被CLDC定義的native code都不允許調用。這意味着應用程序不能下載一個新的含有native code的類庫並使用。 l CLDC規範額外規定了系統類和應用程序類的命名規則。也就是說,為了滿足上面說的沙箱的要求,所有java.*和java.microedition.*都屬於系統類,不能被覆蓋,修改;也不能任意增減。應用程序類不能使用上述包名來實現自己的類。 l 而且,除了調用系統類之外,應用程序只能調用自身JAR包中的類。這樣保證了應用程序不能從其他的應用程序中「偷」數據(或類的實現)來達到自身的目的。 註:在最新的JSR246(Device Management)中,通過設備管理框架(Device Management Framework),滿足一定條件的應用程序有可能訪問其他應用程序的數據,但是對絕大多數應用程序來說,別人的數據仍然是不可以訪問的。(想用楷體,但是機器上沒有除宋體以外的其他字體……哭) 3,端對端的安全機制(end-to-end security) 端對端的安全機制主要指在數據傳輸時的安全,如數字簽名、加密等機制。考慮到網絡不是CLDC設備必須支持的功能,這方面的定義是由上層相應的簡表來完成的,如MIDP;CLDC規範中並沒有詳細的規定。 5.2 CLDC中類的預審核模式 J2SE提供了字節碼的審核機制用於檢查類文件的完整性。該審核機制是在編譯時進行的,其目的是確保類文件中不包含可能破壞系統安全的或是違反了Java語言規範的惡意代碼。其內容主要包括: 1)所有本地變量在使用前必須初始化 2)在構造對象時,其構造函數必須在該對象被使用前調用 3)每個對象的構造方法都必須調用父類的構造方法(要求最先調用java.lang.Object的構造方法) 4)本地變量、實例和靜態成員在聲明時指明的對象類型必須和實際賦值的對象類型一致。例如,給一個聲明成String類型的變量賦予Integer類型的值是不被允許的。 類的審核機制僅僅針對於外來的類文件(比如從網絡上下載的),而對本地文件系統中的類的加載是不用審核的。 CLDC和J2SE一樣,也要求虛擬機能夠辨別並拒絕非法的類文件。但由於J2SE中定義的標準類審核過程對於應用CLDC的小內存消耗的小型設備來說是不現實的,因此CLDC專門定義了其特有的預審核機制。 在CLDC的預審核機制中,要下載的Java類文件的每一個方法都包含了一個堆棧映射屬性,這個屬性是CLDC獨有的,J2SE規範中沒有定義。堆棧映射的屬性會通過虛擬機的預審核器添加到標準的類文件中,該預審核器會分析類中的每一個方法。堆棧映射屬性通常會增加約5%的類的大小。 如圖所示,當程序的源程序被編譯後,必須被預審核器預審核,然後才能生成可以被下載到目標設備上運行的類文件。把一部分的審核任務放在預審核器中完成,可以使與CLDC兼容的虛擬機審核Java類文件時速度更快,並且只需要很少的虛擬機代碼和動態內存,而它們的安全級別相同。因此,在CLDC/MIDP環境下開發程序,其程序經過編譯後,必須經過預審核後才能運行。 特別需要說明的是: 1. 經過預審核器審核過的Java類文件不需要修改就可以直接運行在J2SE和J2EE環境上,這使得移植和相互調用變得非常簡單。 2. 運行時的審核機制CLDC把它交給了設備自己去實現。設備可以根據自身的需要在加載類或是安裝應用程序的過程中執行。在運行時,虛擬機迅速地對字節碼進行線性掃描,將每個有效的指令與合適的堆棧映射項相匹配。運行時的審核過程是建立在預審核機制之上的,所以比預審核還要快,占用的動態內存更少。 5.3 CLDC中的類的文件格式 CLDC要求所有第三方開發的支持CLDC的Java應用程序在公開發布時都要使用JAR包的格式,而且JAR包內的類必須是經過了預審核器審核之後的。同樣的,CLDC要求所有實現CLDC的虛擬機也必須能夠識別和調用JAR包中的文件。
類庫
CLDC標準為了能夠涵蓋儘可能多的設備,其類庫只包含了最小的Java平台特性和API。面對嚴格的內存限制和當前各種各樣的小型設備,CLDC不可能覆蓋全部的這些設備。因此在CLDC的規範中,不可避免的會造成對某些設備要求過高或是對另一些設備要求又太低的現象。 為了確保與其他Java平台的兼容性,絕大多數的CLDC類庫是從J2SE和J2EE中繼承的,是J2SE和J2EE的子集。由於目標設備的特殊性,CLDC類庫在安全、輸入/輸出、用戶界面、網絡和存儲管理等方面沒有全部使用J2SE的實現;其中的部分類庫CLDC進行了重寫,如網絡連接。 如4.3中所介紹的,CLDC的類庫可以分為兩種:一種是從J2SE標準類庫中繼承的;另一種是專門為CLDC設計的(這部分類也可以被映射到J2SE中)。 對於第一種CLDC類庫,包括了J2SE的3個最核心的包java.io、java.lang和java.util。而且這3個包和J2SE相比,也只是J2SE相應包的一個很小的子集。例如java.util的類與接口由J2SE中的53個減少到10個。 對於後一種CLDC類庫,只有描述標準連接框架的javax.microedition. io包,和MIDP中定義的包一起放於javax.microedition包中。 6.1 java.lang包 java.lang包包含了Java語言API的核心部分繼承下來的類,但是CLDC只繼承了J2SE中一半的類,而且一些類中的接口並沒有完全實現。這主要表現在: 1)絕大部分的虛擬機不支持錯誤類和部分異常類被去掉了。 2)不支持Float和Double數據類型及其相應的類 3)ClassLoader、SecurityManager等CLDC規範上沒有說明必須支持的類也不在此包中。 下表給出了CLDC 的java.lang包中的類及類的繼承關係。 java.lang.Object類: Object類中需要注意的有以下兩點: 1. 沒有finalize( )方法。 2. 沒有接口類java.lang.Cloneable,所有CLDC虛擬機的對象都沒有默認的clone()方法。 數據類: 在前面已經提到過多次,CLDC不支持浮點數據類型,核心庫中的java.lang.Floart類和java.lang.Double類以及其他類中與浮點數據相關的方法均不予支持。CLDC支持的數據類型有:Boolean、Byte、Char、Integer、Long、Short和String。 需要注意的是: 1. java.lang.Number不在核心庫中,java.lang.Byte等基本數據類直接從java.lang.Object類繼承。 2.接口類java.lang.Comparable沒有出現在CLDC規範中,所以數據對象之間不能像J2SE那樣直接調用compareTo()方法比較。 3. String類與J2SE相比變化較大,其中去掉了compareToIgnoreCase()、copyValueOf()、equalsIgnoreCase()、split()、match()和intern()等方法;其餘部分方法進行了縮減。 4. java.lang.Math類相對J2SE功能要小很多,只提供了和int、long有關的三組操作。 Class類: forName()方法和newInstance()方法仍然可以用,用來獲得未知的class對象。getResourceAsStream(String name)方法可以找到指定名字的資源,並以InputStream的形式獲得。該方法常用於讀取本地MIDlet JAR包中圖片或者文本文件或是某個Java包。參數——name可以是絕對路徑(以「/」開頭,如/com/sun/MIDlet1/resources/pic.png),也可以是相對於當前MIDlet目錄下的相對路徑(如resources/pic.png)。 System類和Runtime類: Runtime類和System類實現設備底層的操作,這些操作通常會涉及底層。考慮到底層相關的屬性和虛擬機性能等約束的原因,這兩個類都僅僅包含了J2SE有限的幾個方法。 1. 在CLDC的簡表MIDP中定義一些J2SE中沒有的系統屬性(見表2.5)。通過getProperty()方法可以獲得指定的屬性值(String config = System.getProperty("microedition.configuration"))然而,CLDC沒有實現J2SE中的類java.util.Properties。這就意味着,不能通過getProperties( )方法獲得全部系統屬性列表。而且應用程序不能利用setProperty()或setProperties()方法定義自己的屬性。原有的通過JNI連接native code的方法由於JNI的不支持也都被省掉了。其中,如果支持多個簡表,中間用空格區分。 59) 名稱 60) 含義 61) 值 62) microedition.platform 63) 主機平台或設備的名稱 64) 默認值為null 65) microedition.encoding 66) 默認編碼格式 67) 默認值為「ISO8859_1」 68) microedition.configuration 69) 所支持的配置版本 70) 默認值為「CLDC-1.0」 71) microedition.profiles 72) 所支持的簡表名稱 73) 默認值為null 系統屬性列表 2. J2SE中最常用的常量err和out仍然被System類保留了,但是常量in被刪掉了。所以CLDC中沒有標準的輸入數據對象了。 3. 還要注意的是停止虛擬機運行的exit()方法。CLDC雖然允許MIDlet(應用程序)直接調用並執行該方法,但是MIDlet會收到SecurityException的異常。 4. 由於設備的內存限制,J2ME中gc()的使用率比J2SE高出很多,但是其本質和J2SE並沒有區別,垃圾收集的工作全權由系統負責。另外在J2ME中使用gc()時要找準時機。 Thread類和Throwable類: CLDC要求虛擬機必須支持多線程,即使底層平台並不支持。J2SE中對多線程的定義——Tread類、關鍵字synchronized、對象的wait()、notify()和notifyAll()等方法都納入了CLDC規範。然而,CLDC並不支持線程組,也沒有提供TreadGroup類。 還有一些和J2SE的Tread類不同的地方是: 1. 線程不能自己取名,即getName()和setName()方法在CLDC中不予提供。 2. 刪除了resume()、suspend()和stop()方法。這些方法在J2SE中已經是不在推薦使用的了(depredated)。 3. 線程對象沒有destory()、interrupt()和isInterrupted()方法。因此,CLDC的線程必須由程序員自己控制結束(通常用boolean變量+循環來控制),如: Public void run() { While (!threadStopped){ //the actions in the thread } } 4. dumpStack()方法被去掉了,類似的操作會拋出異常。 錯ki/%E7%B1%BB%E5%9B%BE target="_new" class=innerlink>可以看到,CLDC中大多數的異常類是在java.lang包中定義的,而錯誤類僅僅3個。這些錯誤類和異常類都和J2SE中的相同。特別需要注意的是Throwable類中的printStack()方法。該方法的輸出格式由虛擬機的實現自行規定;特別是在Sun的實現KVM中,該方法僅僅會把異常的名字打印出來。 6.2 java.util包 CLDC的java.util包主要包括了集合類和時間、日期的相關的12個類。其中的10個類是從J2SE中繼承來的;Timer和TimerTask類是MIDP增加的類。 集合類: CLDC規範中包含了4個集合類:Hashtable、Stack、Vector和Enumeration。和J2SE相比,它們的功能被大大削減了,這點從繼承關係上就可以看出:J2SE中的集合框架被取消了,它們都直接從java.lang.Object類直接繼承。 Date類: CLDC的Date類比J2SE要簡單的多。Deprecated 構造函數和方法都被除去了;多個Date對象的比較方法只能用equals()來進行。因此,我們不能直接通過Date對象獲得時間(日期)的一部分,如年、月、日等。這些功能僅在Calendar類中有定義。 TimeZone類: CLDC規範規定設備只需要支持其默認的GMT時區。在KVM的實現中,支持GMT和UTC兩種時區表示。 Calendar類: Calendar類是抽象類,沒有直接的構造方法,要構造一個默認的Calendar對象必須調用靜態方法getInstance()。下面列出了Calendar對象不同的構造方法: Calendar cal = Calendar.getInstance(); TimeZone timezone = new TimeZone(); Calendar cal = Calendar.getInstance(timezone); Date date = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(date); 在Date類的介紹中提到過,Date類中不能提取時間的一部分,而和Calendar類一起使用就可以很容易的完成Date對象的分解和加減等的運算。 Calendar類不能以字符串的形式返回年月日,因為CLDC沒有包含java.text包。在KVM的實現中,只能通過toString()方法獲得形如Sat, 9 Apr 2005 12:00:00 UTC的字符串。不同的虛擬機的實現可能會返回不同格式的字符串。 Timer和TimerTask類: MIDP通過Timer和TimerTask類提供了一種實現簡單的多任務調度執行的方法,調度由一個專門的後台線程完成。其中,TimerTask 是用戶定義的需要被調度的所有任務的抽象基類。Timer 類在任務執行的時候負責創建和調度執行線程。這些調度由Timer類的schedule()和scheduleAtFixedRate()方法來完成,而run() 方法用來執行各個任務。此外每個 正在執行的任務必須能夠儘快的終止,因為每個 Timer 對象在同一時間只能執行一個任務。 schedule()和scheduleAtFixedRate()方法都可以通過指定任務的開始時間、延遲時間或者任務的持續時間來調度任務。兩者的區別在於,當某個任務因為某種原因出現一段時間的延遲後,之後所有由schedule()方法調度的任務都會順延;而之後所有由scheduleAtFixedRate()方法調度的任務會自動根據一個固定的頻率來調整。也就是說,在相同的一段時間內,如果用schedule()方法執行10次的任務,用scheduleAtFixedRate()方法調度可能會執行9次或是11次。 另外,TimerTask類提供了cancel()方法用於在任務執行的過程當中強行終止任務,該方法是從Runnable接口類繼承來的。一旦終止了該任務,那麼它將退出任務調度。在任何時間調用cancel()方法都是有效的,即使該任務還一次都沒有執行過。 6.3 java.io包 CLDC的java.io包是J2SE的子集,只提供了相當有限的8位輸入/輸出功能。而且,一些抽象類,像FilerInputStream等,也被省掉了,原先從這些抽象類繼承的類直接從它們的父類InputStream和OutputStream繼承。這裡只表2.5給出了CLDC中java.io包中的類及類的繼承關係。 對於CLDC,InputStream和OutputStream類是讀寫數據的唯一的途徑。無論是本地文件或是網絡連接的讀寫都要通過這兩個類來完成。一個典型的例子就是:MIDlet提供了本地存儲方式——RecordStore,它以字節數組的形式存儲內容。MIDlet需要把要存的內容轉換成ByteArrayInputStream或是DataInputStream對象格式來儲存。同樣的,調用在javax.microedition.rms中操作RecordStore的API所返回的也是ByteArrayOutputStream或是DataOutputStream對象。 由於CLDC不支持浮點數據,因此DataInput和DataOutput接口類只提供了對boolean、char、int、long和short型數據的讀寫操作。 DataInputStream、DataOutputStream類在J2SE中是從FilerInputStream和FilerOutputStream繼承來的。CLDC中FilerInputStream和FilerOutputStream被省掉了,所以DataInputStream和DataOutputStream直接成為了InputStream和OutputStream的子類。DataInputStream類不能直接構造,要通過其他方法獲得。例如,通過javax.microedition. io.Connector中的openDataInputStream方法,這是CLDC通用連接框架(GCF)中從網絡獲取數據流的最長用的方法。而DataOutputStream類可以直接構造,也可以通過如javax.microedition. io.Connector中的openDataOutputStream等方法獲得。 Reader和Writer類從java.lang.Object繼承,基本上與J2SE區別不大。它們的作用是提供有限的國際化支持。J2SE中這是通過Reader和Writer對象實現的,而CLDC中使用了InputStream和OutputStream來完成同樣的功能。 InputStreamReader類用於把8位的輸入數據流轉化成unicode碼。然而,在CLDC規範中僅要求設備支持自身默認的編碼格式,其他的編碼格式可以有選擇的支持。CLDC也不提供可以在運行時把應用程序的編碼自動轉成設備默認編碼格式的功能。系統支持的編碼格式可以從系統屬性microedition.encoding中獲得。如果系統不支持指定的編碼,會拋出UnsupportedEncodingException異常。需mark()和reset()方法;而J2SE中的getEncoding()方法被去掉了。 和InputStreamReader類似,OutputStreamWriter類中也去掉了J2SE中的getEncoding()方法。 PrintStream類直接從OutputStream類繼承,不支持浮點數據的打印。同時需要注意的是,print()和println()不會拋IOException,需要用checkErro()方法查看錯誤狀態。 CLDC的java.io包提供的IOException及其4個子類都和J2SE相同,這裡就不再說明了。 6.4 javax.microedition. io包 javax.microedtion.io包定義了GCF中的類和接口,其中最關鍵的是Connector類和Connection接口。Connector類中定義了靜態方法生成特定類型的Connection,利用這個Connection可以訪問網絡和各種其他設備。