??? 一、引言
Java的設計者企圖建立一個簡單的、面向對象的、智慧的、已經解譯的、強大的、安全的、架構合理的、可移植的、高性能的、多線程的、動態的語言。為使Java對開發者有吸引力,Sun公司融合了類似于C語言的語法和結構。然而Sun最終沒有達到這個目標,Java還是被證明不適合小型的電子設備,這很大程度是因為它大而且速度慢。應用Java程序所需要的處理能力和內存量,對這類設備來說太昂貴了。
然而,Sun公司設計Java時最重要的是平臺無關及網絡集成。一個無須更改能夠在幾種不同硬件和軟件平臺運行的程序,對網絡環境來說是一個理想的程序。對想建立通過網絡來通訊并利用網上資源的分布式程序的開發者來說,一種在任何平臺上都有內置的和標準的網絡支持的語言是一個大實惠。
1、Java語言與嵌入式
對于選用嵌入式編程語言,一般說,越是高級的語言,其編譯和運行庫施加的開銷越大,你的應用程序也越大,越慢。已經公認用匯編語言能寫出最小最快的程序,其次是用C或Forth,接下來較大的是C++或Basic,然后才是Java。因此一般來說,編程人員都會首選匯編和C,而然后才會考慮C++或Java。
但是嵌入式開發者為何要來關注Java呢?筆者以為,隨著不斷增長的市場需求,很多嵌入設備必須適應網上交流的需要,為了迎合此要求,考慮這種到開發Internet應用程序的便利,眾多開發者都發現使用這種語言是有意義的。另一個原因是隨著內存條及32位處理器價格的下降,最初在嵌入系統使用Java太昂貴的問題不再有了。隨著使用Java的成本代價減少,它的很多優點應當被考慮作為嵌入平臺。
2、Java對于嵌入式的優點分析
Java語言的優點在于:它當初就是由理解和信奉網絡計算夢想的一個小巧而專注的開發組設計的,雖然該語言最初的實施方案有點缺陷,有許多后來已被解決了,但為了這個夢想,他們很少在技術上妥協,結果誕生了一種專為以相互通訊為主要目的的設備而設計的語言。
有許多技術上的優點都可能會引導嵌入系統開發者選擇Java,以下就是這些優點(其中有幾個也適用于通用編程)
A)與處理器無關
Java的第一個優點就是與處理器無關,這個優點似乎與嵌入式系統沒什么相干。傳統上,嵌入程序就是針對特定的微處理器設計并在其上運行的,而C語言程序的可移植性則可通過編譯或交叉編譯來保障。
但是在Sun公司的模型中,一個程序可能是存儲在一個系統上,而被下載并運行在另一個完全不同的系統上;設備可能從不同地方下載一些程序來在一個處理器上運行,或者不同的處理器運行一個程序,通過網絡在相互間傳遞數據。使用Java,一個嵌入式系統就可能成為一個通用的通信設備,能下載并運行能完成特定任務的程序。
對嵌入式系統,這是一個新的模型,已經有一些開發者正在向它靠攏。例如,電視機機頂盒的供應商已宣布并入JVM,以使用戶能通過Java applets在他們觀看電視的同時接收到的支持該電視節目的一些內容。這樣你在觀看足球比賽時,看到的支持內容就可以是對球員的技術統計;若你在看電影,看到的支持內容就可以是演員的背景資料。JVM還被并入到移動電話中,這樣用戶可接收股票報價信息、比賽分數及其他即時信息。
筆者以為,這是一個恰當的設計和實施模型。其一是你在選擇開發平臺時更加靈活了。你無需在與目標相同的平臺上開發,也不用去關心交叉編譯,因為Java字節碼能在任何有JVM的操作系統中運行;另一個優點是:幾乎所有的檢測和調試可以獨立于目標設備來進行。但是,一些數據輸入和硬件交互要求在目標(或是很好的仿真系統)上測試。由于個別JVM有時有兼容性的問題,你應該在所有將用到該程序的平臺上測試它。但一般來說,你并不要高級而昂貴的、配備有邏輯探針、ICE以及其它調試工具的、針對目標平臺的開發環境。
B)面向對象的編程
Java是一種純粹面向對象的語言。所有代碼和數據都是某個類的一部分,沒有全局變量或是獨立于類存在的代碼,一個對象是一個類的實例,對象是通過調用操作方法,或者說函數來操作的,而這些方法或函數也是類的一部分,對象的方法就對象的數據進行操作。Java類被組織成一個等級層次,在層次結構中,一個子類能夠繼承其超類的行為,并可用子類所具備的一些特有功能來擴展其超類的功能。對象模型是你能定義對應真實事物的數據結構,使得程序的任務和任務如何實現者二者之間的轉換變得基本上透明。
面向對象的設計和編程的優點在于其開發速度和代碼的可維護性,許多面向對象的開發都能通過利用和更改現存類庫來完成,而不是創造一個新的結構,這就使開發加快了,例如,一個硬件開關能在軟件中使用一個開關對象來實現,該對象包含用于控制和操作開關的所有必需的數據和代碼。面向對象的方法還盡量使用自然的結構,使其有很高的可讀性,且可輕易更改和加強。
C)安全和安全操作
由于有了JVM,一個Java應用程序與操作系統或硬件完全隔絕,因此計算機病毒或其它作祟的的代碼就很難獲得對設備的控制。虛擬機是主機設備和那些可能難以確定其質量和可靠性的軟件之間的一個保護層。
另外,Java設計者從該語言中去掉了指針變量的概念。Java不能任意訪問其內存位置,它們只能讀寫有Java內存分配管理系統創建的對象。由于Java編譯器所強制的嚴格的分類機制,從理論上來說,訪問那些未分配給程序的內存區域是不可能的。這個限制使得要寫惡意代碼的程序變得非常困難了。
對Java applet施加的限制就更加嚴格了。由于Java applet被設計成從Internet上下載,因而被視為不可信任的代碼,除非它包括你已認定為可信任的主機的數字指紋。JVM在內存的一個稱之為sandbox的區域運行諸如applet這種不可信任的代碼。它給每個applet分配資源和特權,并將其限定在這些分配區域范圍中。
D)內存管理
Java的內存管理遠比其他語言簡單,因為它不使用指針。當對象被實例化時,內存被動態分配。正如我們前面分析的,對個別內存地址的訪問被Java的設計者視為一個對安全的潛在危險,因此,訪問也被禁止。而且,Sun的網絡模型已假定你也許不知道目標處理器,而引用專用內存地址變得沒有必要。去掉指針的結果不僅提高了安全性,還簡化了編程,錯誤也減少了。
在C語言中,可以用值或引用的方式來訪問數據。事實上,出于靈活性和控制考慮,非原始數據類型都由引用方式來存取,即通過指針訪問。因此,值和引用的不同變得非常清楚,特別是:因為你不得不使用不同的符號(*和&)來存取數據。要用這兩種不同的訪問方式,你必須清楚理解它們是什么以及你為什么應該使用這一個,而不使用那一個。
在Java中,由值和引用來存儲是無縫的,尤其因為其符號都一樣。兩者間唯一不同在于數據類型本身:所有原始數據類型始終由值的方式存取;所有對象,包括字串、數組以及文件流,始終由引用方式訪問。聲明為原始數據變量類型包含該變量的值,聲明為對象的變量則包含對該對象(即該對象的地址)的一個引用,而非對象自身的引用。僅僅聲明一個對象變量并不給對象分配內存,你必須用“new”關鍵字來分配內存和創建對象。
這兩種方法最根本的不同在于:不可能象在C中那樣就Java內存地址做指針算術或其他操作。Java中對象的地址是相對的(或虛擬的),它由虛擬機任意分配,因此你沒有理由還想要指針地址。
E)垃圾收集
垃圾收集自動收集內存中未引用的內存,并將其歸回空閑內存鏈表中。JVM使用此功能將不在使用的內存還給系統。
當Java程序說明并實例化一個對象或數組時,它僅僅做一個JVM請求,訪問其下面的系統內存(通常是通過主機操作系統)并分配內存,Java的垃圾收集系統通過內存收集對象,然后檢查它們的引用鏈。Java的垃圾收集系統的工作方式一般是搜索內存中的對象,然后檢查它們的引用表。它計算程序中有多少變量當前正在引用每個對象。若對象的引用數目為零,它知道此對象不再在使用了,它的內存可以收回。其結果就是,不必像你在C語言所作的那樣,要人工來釋放分配的內存。在C中,釋放內存是一個必要、耗時且易出錯的細節。Java自動而精確的處理此過程,去除了C/C++程序中那種常見的錯誤致因。
???? F)網絡
由于今天的嵌入式系統通常都是網絡的,采用內置網絡支持的語言節約了在實現網絡協議和通信程序方面耗費的大量時間和努力。在Java中,網絡類包括TCP/IP流和使用TCP及UDP的數據報程序,用于HTTP和URL服務的操作方法,以及錯誤檢查代碼和恢復功能。
雖然實現網絡也可能用其他語言,比如C語言,但那些語言要求特別的附件軟件包,DLL,或其他必須由操作系統,或者第三方銷售提供程序模塊,特別附件通常要求有操作系統或第三方工具的知識,不象Java,有標準的、內置的網絡支持。
Java包括網絡包出于必要,因為設計者不能對一個作為基礎的操作系統的網絡設施做任何假定,他們必須得包括集成網絡程序庫,以確保Java程序能在所有平臺上工作。
G)動態配置
動態配置是指一系統啟動時的用戶制定配置或重新配置。需載入特殊的硬件配置、網絡參數或在引導期間支持特定用途的一些實用程序的系統,常常使用動態配置。
Java以動態捆綁來支持動態配置。當你組成一個程序的各個類文件編譯成字節碼時,在你的類文件之間,或者對JVM包的類(如圖形、網絡以及核心語言支持)引用,還沒有被解決。當JVM載入你的程序時,它動態的載入并捆綁(即鏈接)你的程序引用的所有的類。因此,要改變系統配置,你所需要做的一切就是修正相應的類文件。下一次系統時,JVM自動捆綁新文件到你的程序中,而新的配置將生效執行。
H)異常處理
與許多操作系統和程序不同,對嵌入系統而言,重新啟動通常是無法接受的,就像我們都不希望打電話或者看電視時突然有技術性的中斷一樣。這意味著實際上所有嵌入式系統都必須足夠堅實以截取錯誤來防止它們使程序或更糟的是使整個設備崩潰。
程序錯誤的致因很多。相對來說,很少是因為繼承邏輯錯誤,而大多數程序的崩潰是因為意外輸入,或者是因為程序不能調用系統資源來完成某個特定操作。
在Java中,由拋出(產生)一個異常來提示錯誤。使用專門為異常處理而設計的語句(關鍵字try、catch、和finally),程序就能將其錯誤處理代碼安排到幾個集中區域,try程序塊是程序執行的正常流程。當一個異常發生在try塊(包括該嵌套塊中的各層子程序)中,控制就交給了catch塊。不管是否有異常發生,finally塊中的代碼始終要被執行。未被處理的異常會由調用堆棧自下而上傳播JVM并終止程序。你不再需要動手編程,來將錯誤狀態通過幾層函數調用返回。而是,在錯誤發生由檢測錯誤的代碼直接拋出一個異常。這極大地簡化了應用程序中的錯誤處理代碼,進而獲得更好地錯誤處理效果和更堅實可靠的代碼。
I)線程
大多數操作系統都給一個過程產生和管理多個線程的能力,這些線程彼此獨立地完成不同地任務。但是,很少由程序語言提供對線程管理的直線支持,通常都需要直接調用操作系統功能。Java卻相反,直接在語言提供了產生、管理和協調同步線程地功能。與Java的其他特點一樣,該功能是必要的,因為設計者不敢確定底層的操作系統是否支持多線程。
開發者越來越多的在程序中使用線程,將其作為滿足一個程序不能完成的,通常相互無關的一些任務的一種手段。由于Java對線程有內置語言支持,以Java創建多線程較之與其它語言更簡單、更自然。
J)圖形
JVM包括一個龐大的圖形及窗口支持程序包,稱為Abstract Windowing Toolkit(AWT)。用AWT,你能在應用程序中快速而輕易地創建精致而強大的圖形用戶界面。對于需要精細的用戶界面的嵌入系統來說,AWT能節省大量開發時間,從而是產品更快的走向市場。
評論
查看更多