Java是一種廣泛使用的電腦程式設計語言,擁有跨平台、物件導向、泛型程式設計的特性,廣泛應用於企業級Web應用開發和流動應用開發。
![]() | |
編程範型 | 多重範式:物件導向(類別基礎)、結構化、指令式、泛型、反射、並行計算 |
---|---|
設計者 | 詹姆斯·高斯林 太陽電腦電腦系統 |
實作者 | 甲骨文公司 (太陽電腦電腦系統) |
釋出時間 | 1995年[1] |
目前版本 |
|
型態系統 | 靜態、安全、強型別、標明類型 |
特許條款 | GNU通用公眾特許條款、JCP |
副檔名 | .java、.class、.jar |
網站 | www |
主要實作產品 | |
OpenJDK、GCJ、其他 | |
衍生副語言 | |
泛型Java、Pizza | |
啟發語言 | |
Ada 83、 Generic Java、 | |
影響語言 | |
Ada 2005、 | |
任職於太陽電腦的詹姆斯·高斯林等人於1990年代初開發Java語言的雛形,最初被命名為Oak,目標設置在家用電器等小型系統的程式語言,應用在電視機、電話、鬧鐘、烤麵包機等家用電器的控制和通訊。由於這些智慧型家電的市場需求沒有預期的高,太陽電腦放棄了該項計劃。隨着1990年代互聯網的發展,太陽電腦看見Oak在互聯網上應用的前景,於是改造了Oak,於1995年5月以Java的名稱正式釋出。Java伴隨着互聯網的迅猛發展而發展,逐漸成為重要的網絡程式語言。
Java程式語言的風格十分接近C++語言。繼承了C++語言物件導向技術的核心,捨棄了容易引起錯誤的指標,以參照取代;移除了C++中的運算子重載和多重繼承特性,用介面取代;增加垃圾回收器功能。在Java SE 1.5版本中引入了泛型程式設計、類型安全的列舉、不定長參數和自動裝/拆箱特性。太陽電腦對Java語言的解釋是:「Java程式語言是個簡單、物件導向、分散式、解釋性、健壯、安全、與系統無關、可移植、高效能、多線程和動態的語言」。
Java不同於一般的編譯語言或直譯語言。它首先將原始碼編譯成位元組碼,再依賴各種不同平台上的虛擬機器來解釋執行位元組碼,從而具有「一次編寫,到處執行」的跨平台特性。在早期JVM中,這在一定程度上降低了Java程式的執行效率。但在J2SE1.4.2釋出後,Java的執行速度有了大幅提升。
與傳統型態不同,太陽電腦在推出Java時就將其作為開放的技術。全球的Java開發公司被要求所設計的Java軟件必須相容。「Java語言靠群體的力量而非公司的力量」是太陽電腦的口號之一,並獲得了廣大軟件開發商的認同。這與微軟公司所倡導的注重精英和封閉式的模式完全不同,此外,微軟公司後來推出了與之競爭的.NET平台以及模仿Java的C#語言。後來太陽電腦被甲骨文公司併購[14],Java也隨之成為甲骨文公司的產品。
歷史
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/1/14/James_Gosling_2008.jpg/640px-James_Gosling_2008.jpg)
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Duke_%28Java_mascot%29_waving.svg/100px-Duke_%28Java_mascot%29_waving.svg.png)
語言最開始只是太陽電腦(Sun MicroSystems)公司在1990年12月開始研究的一個內部項目。太陽電腦公司的一個叫做帕特里克·諾頓的工程師被公司自己開發的C++和C語言編譯器搞得焦頭爛額,因為其中的API極其難用。帕特里克決定改用NeXT,同時他也獲得了研究公司的一個叫做「Stealth計劃」的項目的機會。
「Stealth計劃」後來改名為「Green計劃」,詹姆斯·高斯林和麥克·舍林丹(Mike Sheridan)也加入了帕特里克的工作小組。他們和其他幾個工程師一起在加利福尼亞州門羅帕克市沙丘路的一個小工作室裏面研究開發新技術,瞄準下一代智能家電(如微波爐)的程式設計,太陽電腦預料未來科技將在家用電器領域大顯身手。團隊最初考慮使用C++語言,但是很多成員包括太陽電腦的首席科學家比爾·喬伊,發現C++和可用的API在某些方面存在很大問題。
工作小組使用的是嵌入式系統,可以用的資源極其有限。很多成員發現C++太複雜以至很多開發者經常錯誤使用。他們發現C++缺少垃圾回收系統,還有可移植的安全性、分佈程式設計、和多線程功能。最後,他們想要一種易於移植到各種裝置上的平台。
根據可用的資金,喬伊決定開發一種集C語言和Mesa語言大成的新語言,在一份報告上,喬伊把它叫做「未來」,他提議太陽電腦的工程師應該在C++的基礎上,開發一種物件導向的環境。最初,高斯林試圖修改和擴展C++的功能,他自己稱這種新語言為C++ -- [來源請求],但是後來他放棄了。他將要創造出一種全新的語言,被他命名為「Oak」(橡樹),以他的辦公室外的橡樹命名。
就像很多開發新技術的秘密工程一樣,工作小組沒日沒夜地工作到了1993年的夏天,他們能夠演示新平台的一部分了,包括Green作業系統,Oak的程式設計語言,類庫及其硬件。最初的嘗試是面向一種類PDA裝置,被命名為Star7,這種裝置有鮮豔的圖形介面和被稱為「Duke」的智能代理來幫助用戶。1992年12月3日,這台裝置進行了展示。
同年11月,Green計劃被轉化成了「FirstPerson有限公司」,一個太陽電腦的全資子公司,團隊也被重新安排到了帕洛阿爾托。FirstPerson團隊對建造一種高度互動的裝置感興趣,當時代華納發佈了一個關於電視機頂盒的徵求提議書時(Request for proposal),FirstPerson改變了他們的目標,作為對徵求意見書的響應,提出了一個機頂盒平台的提議。但是有線電視業界覺得FirstPerson的平台給予用戶過多的控制權,因此FirstPerson的投標敗給了SGI。與3DO公司的另外一筆關於機頂盒的交易也沒有成功,由於他們的平台不能在電視工業產生任何效益,公司被併回太陽電腦。
由於商標搜尋顯示Oak已被一家顯示卡製造商註冊。於是同年,Oak被改名為Java。當使用十六進制編輯器打開由Java原始碼編譯出的二進制檔案(.class檔案)的話,最前面的32位元將顯示為CA FE BA BE,即詞組「CAFE BABE」(咖啡屋寶貝)。
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/3/38/J-0.23.0.png/640px-J-0.23.0.png)
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/1/16/MHP-software_stack_english.png/320px-MHP-software_stack_english.png)
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Jsxp_arch.png/640px-Jsxp_arch.png)
1994年6月,在同約翰·蓋吉、詹姆斯·高斯林、比爾·喬伊、帕特里克·諾頓、韋恩·羅斯因和埃里克·施密特經歷了一場歷時三天的頭腦風暴後,團隊決定再一次改變努力的目標,這次他們決定將該技術應用於萬維網。他們認為隨着Mosaic瀏覽器的到來,互聯網正在向同樣的高度互動的遠景演變,而這一遠景正是他們在有線電視網中看到的。作為原型,帕特里克·諾頓寫了一個小型萬維網瀏覽器,WebRunner,後來改名為HotJava[15]。
1994年10月,HotJava和Java平台為公司高層進行演示。1994年,Java 1.0a版本已經可以提供下載,但是Java和HotJava瀏覽器的第一次公開發布卻是在1995年3月23日SunWorld大會上進行的。太陽電腦的科學指導約翰·蓋吉宣告Java技術。這個釋出是與網景公司的執行副總裁馬克·安德森的驚人釋出一起進行的,宣佈網景將在其瀏覽器中包含對Java的支援。1996年1月,太陽電腦成立了Java業務集團,專門開發Java技術。
在流行幾年之後,Java在瀏覽器中的地位被逐步侵蝕。它在簡單互動性動畫方面的用途已經完全被Adobe公司的Flash排擠,2005年Java傾向只被用於雅虎遊戲那樣的更為複雜的應用程式。Java同時遭受到來自微軟的反對,他們決定在新版本的Internet Explorer和Windows中不再附帶Java平台。
與此相反,在萬維網的伺服器端和手持裝置上,Java變得更加流行。很多網站在後端使用JSP和其他的Java技術。
在桌面系統上,獨立的Java程式還是相對少見。這是因為Java平台的執行開銷較大,而許多人的電腦上沒有安裝Java,由於網絡頻寬在以前較小,下載Java曾經是個耗時的事情。但是隨着電腦計算能力、網絡頻寬在10年中取得了很大的進步,同時虛擬機器和編譯器的質素得到了提高,許多應用程式得到了廣泛的使用,包括:
- NetBeans和Eclipse等軟件開發工具
- Android作業系統
- JEdit
- Azureus BitTorrent客戶端。
- JNode作業系統
- Apache軟件基金會的Ant、Derby、Hadoop、Jakarta、POI和Tomcat
- JBoss和GlassFish應用伺服器
- EIOffice(永中Office)
- Minecraft
- 純Java 3D遊戲合金戰士Chrome
- IBM Websphere、ColdFusion和WebLogic
- IntelliJ IDEA
目前Java提供以下三個版本:
2006年太陽電腦在JavaOne公佈Java 開放原始碼項目,並推出OpenJDK計劃[16]。Java虛擬機、Java編譯器和Java類庫以GNU通用公眾特許條款公開。
- 1995年5月23日,Java語言誕生
- 1996年1月,第一個JDK-JDK1.0誕生
- 1996年4月,10個最主要的作業系統供應商申明將在其產品中嵌入JAVA技術
- 1996年9月,約8.3萬個網頁應用了JAVA技術來製作
- 1997年2月18日,JDK1.1釋出
- 1997年4月2日,JavaOne會議召開,參與者逾一萬人,創當時全球同類會議規模之紀錄
- 1997年9月,JavaDeveloperConnection社區成員超過十萬
- 1998年2月,JDK1.1被下載超過2,000,000次
- 1998年12月8日,JAVA2企業平台J2EE釋出
- 1999年6月,太陽電腦釋出Java的三個版本:標準版(J2SE)、企業版(J2EE)和微型版(J2ME)
- 2000年5月8日,JDK1.3釋出
- 2000年5月29日,JDK1.4釋出
- 2001年6月5日,NOKIA宣佈,到2003年將出售1億部支援Java的手機
- 2001年9月24日,J2EE1.3釋出
- 2002年2月26日,J2SE1.4釋出,自此Java的計算能力有了大幅提升
- 2004年9月30日18:00PM,J2SE1.5釋出,成為Java語言發展史上的又一里程碑。為了表示該版本的重要性,J2SE1.5更名為Java SE 5.0
- 2005年6月,JavaOne大會召開,太陽電腦公開Java SE 6。此時,Java的各種版本已經更名,以取消其中的數字「2」:J2EE更名為Java EE,J2SE更名為Java SE,J2ME更名為Java ME
- 2006年12月,太陽電腦釋出JRE6.0
- 2009年12月,太陽電腦釋出Java EE 6
- 2010年11月,由於Oracle公司對於Java社群的不友善,因此Apache揚言將退出JCP[17]
- 2011年7月28日,Oracle公司發佈Java SE 7
- 2014年3月18日,Oracle公司釋出Java SE 8
- 2017年9月21日,Oracle公司釋出Java SE 9
- 2018年3月21日,Oracle公司釋出Java SE 10
- 2018年9月25日,Oracle公司釋出Java SE 11 (LTS)
- 2019年3月,Oracle公司釋出Java SE 12
- 2019年9月,Oracle公司釋出Java SE 13
- 2020年3月,Oracle公司釋出Java SE 14
- 2020年9月,Oracle公司釋出Java SE 15
- 2021年3月,Oracle公司釋出Java SE 16
- 2021年9月,Oracle公司釋出Java SE 17
- 2022年3月,Oracle公司釋出Java SE 18
- 2022年9月,Oracle公司釋出Java SE 19
- 2023年3月,Oracle公司釋出Java SE 20
- 2023年9月,Oracle公司釋出Java SE 21
語言特性
Java之所以被開發,是要達到以下五個目的:
- 應當使用物件導向程式設計方法學
- 應當允許同一程式在不同的電腦平台執行
- 應當包括內建的對電腦網絡的支援
- 應當被設計成安全地執行遠端程式碼
- 應當易於使用,並借鑑以前那些物件導向語言(如C++)的長處。
Java技術主要分成幾個部分:Java語言、Java執行環境、類別館。一般情況下說Java時並不區分指的是哪個部分。
Java在1.5版本時,做了重大改變,太陽電腦並1.5版本重新命名為Java 5.0。
Java的特點之一就是物件導向,是程式設計方法的一種。「物件導向程式語言」的核心之一就是開發者在設計軟件的時候可以使用自訂的類型和關聯操作。程式碼和數據的實際集合體叫做「對象」。一個對象可以想像成繫結了很多「行為(程式碼)」和「狀態(數據)」的物體。對於數據結構的改變需要和程式碼進行通訊然後操作,反之亦然。物件導向設計讓大型軟件工程的計劃和設計變得更容易管理,能增強工程的健康度,減少失敗工程的數量。
跨平台性是Java主要的特性之一,跨平台使得用Java語言編寫的程式可以在編譯後不用經過任何更改,就能在任何硬件裝置條件下執行。這個特性經常被稱為「一次編譯,到處執行」。
執行Java應用程式必須安裝Java 執行時環境(Java Runtime Environment,JRE),JRE包括Java虛擬機器(Java Virtual Machine,JVM),以及Java平台核心類和基礎Java 平台庫。[18]通過JVM才能在電腦系統執行Java應用程式(Java Application),這與.Net Framework的情況一樣,所以電腦上沒有安裝JVM,那麼這些java程式將不能夠執行。
實現跨平台性的方法是大多數編譯器在進行Java語言程式的編碼時候會生成一個用位元組碼寫成的「半成品」,這個「半成品」會在Java虛擬機器(解釋層)的幫助下執行,虛擬機器會把它轉換成當前所處硬件平台的原始程式碼。之後,Java虛擬機器會打開標準庫,進行數據(圖片、線程和網絡)的存取工作。主要注意的是,儘管已經存在一個進行程式碼翻譯的解釋層,有些時候Java的位元組碼程式碼還是會被JIT編譯器進行二次編譯。
有些編譯器,比如GCJ,可以自動生成原始程式碼而不需要解釋層。但是這些編譯器所生成的程式碼只能應用於特定平台。並且GCJ目前只支援部分的Java API。
甲骨文公司對於Java的特許是「全相容的」,這也導致了微軟和太陽電腦關於微軟的程式不支援RMI和JNI介面、並且增加特性為己所用的法律爭端。太陽電腦最終贏得了官司,獲得了大約兩千萬美元的賠償,法院強制要求微軟執行太陽電腦關於Java的特許要求。作為回應,微軟不再在Windows系統中捆綁Java,最新的Windows版本,Windows Vista和Internet Explorer 7.0版本也不再提供對於Java應用程式和控制項的支援。但是太陽電腦和其他使用Java執行時系統的公司在Windows作業系統下對用戶提供無償的第三方外掛程式和程式支援。
Java語言在最開始應用的時候是沒有解釋層的,所有需要編譯的程式碼都直接轉換成機器的原始程式碼。這樣做雖然使程式獲得了最佳的效能,但是導致程式異常臃腫。從JIT技術開始,Java的程式都經過一次轉換之後才變成機械碼。很多老牌的第三方虛擬機器都使用一種叫做「動態編譯」的技術,也就是說虛擬機器即時監測和分析程式的執行行為,同時選擇性地對程式所需要的部分進行編譯和最佳化。所有這些技術都改善了程式碼的執行速度,但是又不會讓程式的體積變得失常。
程式的輕便性事實上是軟件編寫很難達到的一個目標,Java雖然成功地實現了「一次編譯,到處執行」,但是由於平台和平台之間的差異,所編寫的程式在轉換程式碼的時候難免會出現微小的、不可察覺的錯誤和意外。有些程式設計師對此非常頭疼,他們嘲笑Java的程式不是「一次編譯,到處執行」,而是「一次編譯,到處除錯」。以Java AWT為例,早期Java AWT內提供的按鈕、文字區等均是以電腦系統所預設的樣式而顯示。這令Java程式在有些沒有提供圖案的電腦系統產生錯誤(在Microsoft Windows設有視窗管理員,在一些Linux distribution則沒有)。後來太陽電腦針對Java AWT一些問題而推出Java Swing。
平台無關性讓Java在伺服器端軟件領域非常成功。很多伺服器端軟件都使用Java或相關技術建立。
C++語言被用戶詬病的原因之一是大多數C++編譯器不支援垃圾收集機制。通常使用C++編程的時候,程式設計師於程式中初始化對象時,會在主機記憶體堆疊上分配一塊記憶體與地址,當不需要此對象時,進行解構或者刪除的時候再釋放分配的記憶體地址。如果對象是在堆疊上分配的,而程式設計師又忘記進行刪除,那麼就會造成記憶體洩漏(Memory Leak)。長此以往,程式運行的時候可能會生成很多不清除的垃圾,浪費了不必要的記憶體空間。而且如果同一記憶體地址被刪除兩次的話,程式會變得不穩定,甚至崩潰。因此有經驗的C++程式設計師都會在刪除之後將指標重設為NULL,然後在刪除之前先判斷指標是否為NULL。
C++中也可以使用「智能指標」(Smart Pointer)或者使用C++寄存擴展編譯器的方法來實現自動化記憶體釋放,智能指標可以在標準類庫中找到,而C++寄存擴展被微軟的Visual C++ 7.0及以上版本所支援。智能指標的優點是不需引入緩慢的垃圾收集機制,而且可以不考慮線程安全的問題,但是缺點是如果不善使用智能指標的話,效能有可能不如垃圾收集機制,而且不斷地分配和釋放記憶體可能造成記憶體碎片,需要手動對堆進行壓縮。除此之外,由於智能指標是一個基於模板的功能,所以沒有經驗的程式設計師在需要使用多態特性進行自動清理時也可能束手無策。
Java語言則不同,上述的情況被自動垃圾收集功能自動處理。對象的建立和放置都是在記憶體堆疊上面進行的。當一個物件沒有任何參照的時候,Java的自動垃圾收集機制就發揮作用,自動刪除這個物件所佔用的空間,釋放記憶體以避免記憶體洩漏。
注意程式設計師不需要修改finalize方法,自動垃圾收集也會發生作用。但是記憶體洩漏並不是就此避免了,當程式設計師疏忽大意地忘記解除一個物件不應該有的參照時,記憶體洩漏仍然不可避免。
不同廠商、不同版本的JVM中的記憶體垃圾回收機制並不完全一樣,通常越新版本的記憶體回收機制越快,IBM、BEA、太陽電腦等等開發JVM的公司都曾宣稱過自己製造出了世界上最快的JVM,JVM效能的世界紀錄也在不斷的被打破並提高。
IBM有一篇有關Java記憶體回收機制比不啟用垃圾收集機制的C++記憶體處理快數倍的技術文章[19],而著名的Java技術書籍《Java編程思想》(Thinking in Java)也有一段論述Java記憶體及效能達到甚至超過C++的章節[20]。
編寫Java程式前應注意以下幾點:
- 大小寫敏感:Java是大小寫敏感的,這就意味着識別碼
Hello
與hello
是不同的。 - 類名:對於所有的類來說,類名的首字母應該大寫。如果類名由若干單詞組成,那麼每個單詞的首字母應該大寫,例如
MyFirstJavaClass
。 - 方法名:所有的方法名都應該以小寫字母開頭。如果方法名含有若干單詞,則後面的每個單詞首字母大寫,例如
myFirstJavaMethod
。 - 原始檔名:原始檔名必須和檔案內名字唯一且公開(由public 關鍵詞修飾)的類名相同。當儲存檔案的時候,你應該使用該類名作為檔名儲存(切記Java是大小寫敏感的),檔名的字尾為
.java
。(如果檔名和類名不相同則會導致編譯錯誤)。 - 主方法入口:所有的Java程式由
public static void main(String[] args)
方法開始執行。
下面列出了Java關鍵字。這些關鍵字不能用於常數、變數、和任何識別碼的名稱。
類別 | 關鍵字 | 說明 |
---|---|---|
訪問控制 | private | 私有的 |
protected | 受保護的 | |
public | 公共的 | |
類、方法和變數修飾詞 | abstract | 聲明抽象 |
class | 類 | |
extends | 擴充,繼承 | |
final | 最終值,不可改變的 | |
implements | 實現(介面) | |
interface | 介面 | |
native | 本地,原生方法(非Java實現) | |
new | 新,建立 | |
static | 靜態 | |
strictfp | 嚴格,精準 | |
synchronized | 線程,同步 | |
transient | 短暫 | |
volatile | 易失 | |
程式控制陳述式 | break | 跳出迴圈 |
case | 定義一個值以供switch選擇 | |
continue | 繼續 | |
default | 預設 | |
do | 執行 | |
else | 否則 | |
for | 迴圈 | |
if | 如果 | |
instanceof | 實例 | |
return | 返回 | |
switch | 根據值選擇執行 | |
while | 迴圈 | |
錯誤處理 | assert | 斷言表達式是否為真 |
catch | 捕捉異常 | |
finally | 有沒有異常都執行 | |
throw | 投擲一個異常對象 | |
throws | 聲明一個異常可能被投擲 | |
try | 擷取異常 | |
包相關 | import | 引入 |
package | 包 | |
基本類型 | boolean | 布林型 |
byte | 位元組型 | |
char | 字元型 | |
double | 雙精度浮點 | |
float | 單精度浮點 | |
int | 整型 | |
long | 長整型 | |
short | 短整型 | |
null | 空 | |
變數參照 | super | 父類別,超類 |
this | 本類 | |
void | 無返回值 | |
保留關鍵字 | goto | 是關鍵字,但不能使用 |
const | 是關鍵字,但不能使用 |
- 註釋
註釋的作用:標識程式是幹什麼的,以及它是如何構建的。註釋幫助程式設計師進行相互溝通以及理解程式。註釋不是程式語言,所以編譯器編譯程式時忽略它們。
Java內建了建立介面的類別,可以這樣使用:
public interface Deleteable {
void delete();
}
這段程式碼的意思是任何實現(implement)Deleteable
介面的類別都必須實現delete()
方法。每個類別對這個方法的實現可以自行客製化。由此概念可以引出很多種使用方法,下面是一個類別的例子:
public class Fred implements Deleteable {
// 必須實作Deleteable介面中的delete方法
@Override
public void delete() {
// 實作的程式碼
}
// 這個類別也可以包含其他方法
public void doOtherStuff() {
}
}
在另外一個類別中,可以使用這樣的程式碼:
public void deleteAll(Deleteable [] list){
for(int i = 0; i < list.length; i++){
list[i].delete();
}
}
因為佇列中所有的對象都可以使用delete()
方法。Deleteable
佇列中包含Fred
對象的參照,而這個類別和其他Deleteable
類別在使用deleteAll()
方法時候不需要進行任何改變。
之所以這樣做就是為了在介面的執行和其程式碼之間進行區別。舉例來說,一個名叫Collection
的介面可以包含任何對象所需要的引入、轉換和儲存數據的方法,其他的類都可以使用這個介面。但是這個介面可以是一個可重定義大小的佇列、一個鏈結串列或者是其他功能的集合。
這種特性其實是一種折中的辦法。Java的設計者們不想讓Java有多重繼承的特性,因為C++的多重繼承顯示了這種特性的困難。Java的介面功能可以提供同樣的功能,但是又不會很複雜。
在Java語言中,應用程式介面(API)化身成類別,並且分組成為套件。每個包中包含有相關的介面和類。對於不同的平台,Java提供了不同版本的包。API的設定由太陽電腦和其他公司通過JCP(Java社群程式)決定。任何公司和個人都可以參與這個工程,對API進行設計。2004年,IBM和BEA公司準備聯合對官方的Java開源軟件工程進行支援,但是2005年初,太陽電腦拒絕了這個支援。
Hello World
下面這個程式顯示「Hello world!」然後結束執行,注意java.lang
套件是自動載入的,所以不需要在程式之前加入import java.lang.*;
class HelloWorld {
public static void main(String[] args) {
System.out.println("hello, world!");
}
}
關於Java的批評
![Thumb](http://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Java_Ring.jpg/640px-Java_Ring.jpg)
Java試圖通過新的方式解決軟件編寫的複雜性。很多人認為Java語言做到了它承諾的一切,然而,某些情況下,Java會將簡單問題導向複雜化。儘管Java並不是一門完美的語言,但它的出現確實給大規模軟件協同開發提供了新的思路。
並不是所有的工程和環境需要企業等級的複雜性,比如一個簡單的個人網站或者獨自編程的程式師所寫的程式。這些程式師會發現Java的複雜管理對於自己要做的程式來說過於強大了。一些人覺得Java在物件導向上面做的沒有Ruby和Smalltalk純粹。但是最新出現的用Java實現的語言Groovy解決了這些問題。
作為一種已經建立的新技術,Java顯然綜合了很多語言的特性,比如C++、C語言、Python等等。一些對於Java的評論認為Java的不變性在動搖。
有些程式師不喜歡原始類型(primitive type)和類別(class)的分離,尤其是那些曾經使用過Smalltalk和Ruby的程式設計師。Java的代碼相對於其他的代碼來說過於冗長,這與它的輕便化聲明相違背。此外Java一般也會默認式的自動植入過多的標準庫代碼,導致整體運行會出現緩慢
Java是一種單繼承的語言。這也導致了程式師在試圖使用多重繼承時候的不便,而很多語言都可以使用這個特性。但是Java可以使用介面類,把多重繼承可能導致的風險減少到最小。Java不支援運算子重載,這是為了防止運算子重載使得代碼的功能變得不清晰。但是用Java實現的語言Groovy可以進行運算子重載。過去Java對於文字的操作和其他語言,比如Perl和PHP相比差的較多,但Java在1.4版本時候引入了正則表達式。
使用Swing平臺編寫的帶有GUI(圖形用戶介面)的程式和其他原始程式非常不同。選用AWT工具包編寫程式的程式師看到的都是原始介面,而且也無法獲得先進的GUI編程支援,如果使用的話,就要提供每個平臺上面所需的API,這將是一項龐大的工程。Swing則是完全用Java語言所寫的程式,避免了介面元素重複的問題,只使用所有平臺都支援的最基本的繪圖機制。但是很多用戶不知道如何在Java風格和Windows風格之間進行轉換,結果造成了Java程式的介面在很多程式中非常特殊。蘋果電腦已經提供了優化過的Java運行時程式,包含了Mac OS X的經典Aqua介面風格。
在IBM捐贈給Eclipse基金會的SWT介面框架中,用戶會看到熟悉的本地風格介面。但這又引起了不同喜好的開發人員之間的爭論。
由於Java編譯器和虛擬機的不同對Java代碼的效能影響比語言本身的影響大的多,所以統一討論Java的程式的效能經常是有誤導性的。據IBM的資料,在同樣的硬件上2001年時的IBM JDK版本的效能是1996年的JDK版本的十倍左右。[22]而即使是在同一時期,不同公司的JDK和JRE的效能也不一樣,比如太陽電腦、IBM、BEA等公司都有自己開發的JDK和JRE。
Java語言的一些特性不可避免的有額外的效能代價,例如陣列範圍檢查、運行時類型檢查等等。Java程式的效能還會因為不同的動態複雜性和垃圾處理機制使用的多少而各有不同。如果JVM的實現比較優化的話,那麼這些功能甚至可以增加記憶體分配的效能。這和總是使用STL或者寄存C++的程式的情況類似。
儘管如此,仍然有許多人認為Java的效能低。這部分歸因於太陽電腦最初的JVM實現使用未優化的解釋機制來執行位元組碼。一些新版本的JVM使用Just-In-Time(JIT)編譯器,在載入位元組碼的時候將其編譯成針對運行環境的本地代碼來實現一些本地編譯器的優化特性。Just-In-Time機制和本地編譯的效能比較仍舊是一個有爭議的話題。JIT編譯需要很多時間,對於運行時間不長或者代碼很多的大型程式並不適宜。但是不算JIT編譯階段的話,程式的運行效能在很多JVM下可以和本地編譯的程式一爭短長,甚至在一些計算比較密集的數值計算領域也是這樣。目前,Java已經使用更先進的HotSpot技術來代替JIT技術,Java的效能有了更進一步的提升。另外,在使用-server選項運行Java程式時,也可以對Java進行更深入的優化,比如在運行時將調用較多的方法內聯(inline)到程式中來提高運行速度,這就是所謂的「動態優化」,而本地編譯器是無法做到這一點的;這也是一些Java代碼比對應用C/C++等語言編寫的本地代碼運行的更快的原因之一。微軟的.NET平臺也使用JIT編譯器,所以也有類似問題。
Java的設計目的主要是安全性和可攜性,所以對於一些特性,比如對硬件架構和記憶體地址的直接訪問都被去除了。如果需要間接調用這些底層功能的話,就需要使用JNI(Java本地介面)來調用本地代碼,而間接訪問意味着頻繁調用這些特性時效能損失會很大,微軟的.NET平臺也有這樣的問題。所以到目前為止,效能敏感的代碼,例如驅動程式和3D電子遊戲,還是大多使用本地編譯,甚至直接以不直接支援物件導向的C語言或機械碼編寫。但最近已經有了許多用純Java編寫的3D遊戲,其效果與用C語言編寫的不相上下,例如「合金戰士」(英文名:Chrome)。這主要是因為新版的Java 3D技術已經能像C++一樣調用硬件加速,也就是使用顯示卡來加速,無論是C++還是Java語言寫的3D遊戲都是使用顯示卡及GPU來處理,從而使得CPU可以專注於其他方面的工作。
用途
- 桌面GUI應用程式:
Java通過抽象窗口工具包(AWT),Swing和JavaFX等多種方式提供GUI開發。雖然AWT包含許多預先構建的組件,如選單,按鈕,列表以及眾多第三方組件,但Swing(一個GUI小部件工具包)還提供某些進階組件,如樹,表格,捲動窗格,索引標籤式面板和列表。JavaFX是一組圖形和媒體包,提供了Swing互操作性,3D圖形功能和自包含的部署模型,可以快速編寫Java小應用程式和應用程式的指令碼。[23]
- 流動應用程式:
Java Platform,Micro Edition(Java ME或J2ME)是一個跨平台框架,用於構建可在所有Java支援的裝置(包括功能電話和智能電話)上執行的應用程式。此外,最受歡迎的流動作業系統之一的Android應用程式通常使用Android軟件開發套件(SDK)或其他環境在Java中編寫指令碼。
- 嵌入式系統:
從微型晶片到專用電腦的嵌入式系統是執行專門任務的大型電腦電系統的組件。諸如SIM卡,藍光光碟播放器,公用事業儀表和電視機等多種裝置都使用嵌入式Java技術。據甲骨文公司稱,100%的藍光光碟播放器和1.25億台電視裝置都採用Java技術。
- Web應用程式:
Java通過Servlets,Struts或JSP提供對Web應用程式的支援。程式語言提供的簡單程式設計和更高的安全性使得大量政府應用程式可用於基於Java的健康,社會安全,教育和保險。Java也可以使用Broadleaf等開源電子商務平台開發電子商務Web應用程式。
- 分散式系統:
Java更多時候用於構建大型分散式應用, 基於Java的分散式生態非常豐富, 各種成熟的基礎組件幫助Java開發者迅速搭建起分散式系統. 比較著名的分散式框架有: Spring Cloud, Dubbo, ZooKeeper等。
- Web伺服器和應用程式伺服器:
今天的Java生態系統包含多個Java Web伺服器和應用程式伺服器。雖然Apache Tomcat,Simple,Jo !, Rimfaxe Web伺服器(RWS)和Project Jigsaw佔據了Web伺服器空間,但WebLogic,WebSphere和Jboss EAP在商業應用伺服器領域佔據重要地位[24]。
- 企業應用程式:
Java企業版(Java EE)是一種流行的平台,為指令碼和執行企業軟件(包括網絡應用程式和Web服務)提供API和執行時環境。甲骨文宣稱Java可以在97%的企業電腦上執行。Java憑藉更高的效能保證和更快的計算能力使得像Murex這樣的高頻交易系統可以被編入指令碼中。同時它也是各種銀行應用程式的中樞,它們將Java從前端用戶端執行到後端伺服器端。
- 科學應用:
Java是許多軟件開發人員用於編寫涉及科學計算和數學運算的應用程式的選擇之一。這些程式通常被認為是快速和安全的,具有更高的可攜式性和低維護性。像MATLAB這樣的應用程式使用Java來作為互動用戶介面和作為核心系統的一部分。