Java是一種計算機編程語言,擁有跨平臺、面向對象、泛型編程的特性,普遍應用於企業級Web應用開發和移動應用開發。java
任職於太陽微系統的詹姆斯•高斯林等人於1990年代初開發Java語言的雛形,最初被命名爲Oak,目標設置在家用電器等小型系統的程序語言,應用在電視機、電話、鬧鐘、烤麪包機等家用電器的控制和通訊。因爲這些智能化家電的市場需求沒有預期的高,Sun公司放棄了該項計劃。隨着1990年代互聯網的發展,Sun公司看見Oak在互聯網上應用的前景,因而改造了Oak,於1995年5月以Java的名稱正式發佈。Java伴隨着互聯網的迅猛發展而發展,逐漸成爲重要的網絡編程語言。程序員
Java編程語言的風格十分接近C++語言。繼承了C++語言面向對象技術的核心,Java捨棄了C++語言中容易引發錯誤的指針,改以引用替換,同時移除原C++與原來運算符重載,也移除多重繼承特性,改用接口替換,增長垃圾回收器功能。在Java SE 1.5版本中引入了泛型編程、類型安全的枚舉、不定長參數和自動裝/拆箱特性。太陽微系統對Java語言的解釋是:「Java編程語言是個簡單、面向對象、分佈式、解釋性、健壯、安全與系統無關、可移植、高性能、多線程和動態的語言。」正則表達式
Java不一樣於通常的編譯語言或直譯語言。它首先將源代碼編譯成字節碼,而後依賴各類不一樣平臺上的虛擬機來解釋執行字節碼,從而實現了「一次編寫,處處運行」的跨平臺特性。在早期JVM中,這在必定程度上下降了Java程序的運行效率。但在J2SE1.4.2發佈後,Java的運行速度有了大幅提高。數據庫
與傳統型態不一樣,Sun公司在推出Java時就將其做爲開放的技術。全球數以萬計的Java開發公司被要求所設計的Java軟件必須相互兼容。「Java語言靠羣體的力量而非公司的力量」是 Sun公司的口號之一,並得到了廣大軟件開發商的認同。這與微軟公司所倡導的注重精英和封閉式的模式徹底不一樣,此外,微軟公司後來推出了與之競爭的.NET平臺以及模仿Java的C#語言。後來Sun公司被甲骨文公司併購,Java也隨之成爲甲骨文公司的產品。編程
Java語言之父-詹姆斯•高斯林數組
Java之因此被開發,是要達到如下五個目的:瀏覽器
Java技術主要分紅幾個部分:Java語言、Java運行環境、類庫。通常狀況下說Java時並不區分指的是哪一個部分。安全
Java在1.5版本時,作了重大改變,太陽公司並1.5版本重命名爲Java 5.0。服務器
Java的特色之一就是面向對象, 是程序設計方法的一種。「面向對象程序設計語言」的核心之一就是開發者在設計軟件的時候可使用自定義的類型和關聯操做。代碼和數據的實際集合體叫作「對 象」。一個對象能夠想象成綁定了不少「行爲(代碼)」和「狀態(數據)」的物體。對於數據結構的改變須要和代碼進行通訊而後操做,反之亦然。面向對象設計 讓大型軟件工程的計劃和設計變得更容易管理,能加強工程的健康度,減小失敗工程的數量。網絡
Java語言的第二個特性就是跨平臺性,也就是說使用Java語言編寫的程序能夠在編譯後不用通過任何更改,就能在任何硬件設備條件下運行。這個特性常常被稱爲「一次編譯,處處運行」。
執行Java應用程序必須安裝Java Runtime Environment(JRE),JRE內部有一個Java虛擬機(Java Virtual Machine,JVM)以及一些標準的類庫(Class Library)。經過JVM才能在電腦系統執行Java應用程序(Java Application),這與.Net Framework的狀況同樣,因此電腦上沒有安裝JVM,那麼這些程序將不可以執行。
實現跨平臺性的方法是大多數編譯器在進行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語言使用解釋層最初是爲了輕巧性。因此這些程序的運行效率比C語言和C++要低不少,用戶也對此很有微詞。不少最近的調查顯示Java的程序運行速度比幾年前要高出許多,有些一樣功能的程序的效率甚至超過了C++和C語言編寫的程序[來源請求]。
Java語言在最開始應用的時候是沒有解釋層的,全部須要編譯的代碼都直接轉換成機器的原始代碼。這樣作的後果就是得到了最佳的性能,可是程序臃腫異常。從JIT技術開始,Java的程序都通過一次轉換以後才變成機器碼。不少老牌的第三方虛擬機都使用一種叫作「動態編譯」的技術,也就是說虛擬機實時監測和分析程序的運行行爲,同時選擇性地對程序所須要的部分進行編譯和優化。全部這些技術都改善了代碼的運行速度,可是又不會讓程序的體積變得失常。
程序的輕便性事實上是軟件編寫很難達到的一個目標,Java雖然成功地實現了「一次編譯,處處運行」,可是因爲平臺和平臺之間的差別,所編寫的程序 在轉換代碼的時候不免會出現微小的、不可察覺的錯誤和意外。有些程序員對此很是頭疼,他們嘲笑Java的程序不是「一次編譯,處處運行」,而是「一次編 譯,處處調試」。以Java AWT爲例,早期Java AWT內提供的按鈕、文字區等均是以電腦系統所默認的樣式而顯示。這令Java程序在有些沒有提供圖案的電腦系統產生錯誤(在Microsoft Windows設有窗口管理器,在一些Linux distribution則沒有)。後來SUN公司針對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、SUN等等開發JVM的公司都曾宣稱過本身製造出了世界上最快的JVM[來源請求],JVM性能的世界紀錄也在不斷的被打破並提升。
IBM有一篇有關Java內存回收機制比不激活垃圾收集機制的C++內存處理快數倍的技術文章[14],而著名的Java技術書籍《Java編程思想》(Thinking in Java)也有一段論述Java內存及性能達到甚至超過C++的章節[15] 。
編寫Java程序前應注意如下幾點:
關鍵字 下面列出了Java關鍵字。這些關鍵字不能用於常量、變量、和任何標識符的名稱。
關鍵字 | 描述 |
---|---|
abstract | 抽象方法,抽象類的修飾符 |
assert | 斷言條件是否知足 |
continue | 不執行循環體剩餘部分 |
default | switch語句中的默認分支 |
do-while | 循環語句,循環體至少會執行一次 |
double | 64-bit雙精度浮點數 |
else | if條件不成立時執行的分支 |
enum | 枚舉類型 |
extends | 表示一個類是另外一個類的子類 |
final | 表示定義常量 |
finally | 不管有沒有異常發生都執行代碼 |
float | 32-bit單精度浮點數 |
for | for循環語句 |
goto | 用於流程控制 |
if | 條件語句 |
implements | 表示一個類實現了接口 |
import | 導入類 |
instanceof | 測試一個對象是不是某個類的實例 |
int | 32位整型數 |
interface | 接口,一種抽象的類型,僅有方法和常量的定義 |
long | 64位整型數 |
native | 表示方法用非java代碼實現 |
new | 分配新的類實例 |
package | 一系列相關類組成一個包 |
private | 表示私有字段,或者方法等,只能從類內部訪問 |
protected | 表示保護類型字段 |
public | 表示共有屬性或者方法 |
return | 方法返回值 |
short | 16位數字 |
static | 表示在類級別定義,全部實例共享的 |
strictfp | 浮點數比較使用嚴格的規則 |
super | 表示基類 |
switch | 選擇語句 |
synchronized | 表示同一時間只能由一個線程訪問的代碼塊 |
this | 調用當前實例或者調用另外一個構造函數 |
throw | 拋出異常 |
throws | 定義方法可能拋出的異常 |
transient | 修飾不要序列化的字段 |
try | 表示代碼塊要作異常處理 |
void | 標記方法不返回任何值 |
volatile | 標記字段可能會被多個線程同時訪問,而不作同步 |
while | while循環 |
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的設定由sun公司和其餘公司經過JCP(Java社區程序)決定。任何公司和我的均可以參與這個工程,對API進行設計。2004年,IBM和BEA公司準備聯合對官方的Java開源軟件工程進行支持,可是2005年初,sun公司拒絕了這個支持。
並非全部的工程和環境須要企業檔次的複雜性,好比一個簡單的我的網站或者獨自編程的程序師所寫的程序。這些程序師會發現Java的複雜管理對於本身要作的程序來講過於強大了。一些人以爲Java在面向對象上面作的沒有Ruby和Smalltalk純粹。可是最新出現的用Java實現的語言Groovy解決了這些問題。
做爲一種已經建立的新技術,Java顯然綜合了不少語言的特性,好比C++、C語言、Python等等。一些對於Java的評論認爲Java的不變性在動搖。
有些程序師不喜歡原始類型(primitive type)和類別(class)的分離,尤爲是那些曾經使用過Smalltalk和Ruby的程序師。Java的代碼相對於其餘的代碼來講過於冗長,這與它的輕便化聲明相違背。
Java是一種單層繼承的語言。這也致使了程序師在試圖使用多重繼承時候的不便,而不少語言均可以使用這個特性。可是Java可使用接口類,把多重繼承可能致使的風險減小到最小。Java不支持運算符重載,這是爲了防止運算符重載使得代碼的功能變得不清晰。可是用Java實現的語言Groovy能夠進行運算符重載。過去Java對於文本的操做和其餘語言,好比Perl和PHP相比差的較多,但Java在1.4版本時候引入了正則表達式。
- 至Java 1.7爲止,Java語言不支持閉包(closure)和混入(mixin)特性。
- Java 1.8加入閉包(Lambda Expressions) 。
使用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版本的十倍左右。見IBM東京研究院的數據:http://www.is.titech.ac.jp/ppl2004/proceedings/ishizaki_slides.pdf而即便是在同一時期,不一樣公司的JDK和JRE的性能也不同,好比SUN、IBM、BEA等公司都有本身開發的JDK和JRE。
Java語言的一些特性不可避免的有額外的性能代價,例如數組範圍檢查、運行時類型檢查等等。Java程序的性能還會由於不一樣的動態複雜性和垃圾處 理機制使用的多少而各有不一樣。若是JVM的實現比較優化的話,那麼這些功能甚至能夠增長內存分配的性能。這和老是使用STL或者託管C++的程序的狀況類 似。
儘管如此,仍然有許多人認爲Java的性能低。這部分歸因於Sun公司最初的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能夠專一於其餘方面的工做。
Java平臺即由Java編程語言所撰寫的軟件賴以運行的平臺,是Java軟件和電腦系統的中介,最初被設計用在 Applet 等桌面端程序,不事後來逐漸轉移到服務端的運用。
Java 運行環境,即Java Runtime Environment
,簡稱爲JRE,是在任何平臺上運行Java編寫的程序都須要用到的軟件。終端用戶能夠以軟件或者插件方式獲得和使用 JRE。Sun 公司還發布了一個JRE的更復雜的版本,叫作JDK,即Java 2開發包,裏面包含了Java須要的編譯器、參考文檔和調試器等。
根據Sun公司的統計,安裝Java運行環境的我的計算機已經超過7億。[1]自從Sun指控微軟添加Windows特效類文件到Java運行環境(JRE),並經過Visual J++運行這些類文件,微軟再也不綁定Java運行環境到Windows操做系統。Apple的Mac OS X通常默認綁定Java運行環境, 並且許多Linux發行版也綁定一些兼容的自由軟件包GNU Classpath。[2]
一些Java軟件被桌面計算機普遍應用,好比NetBeans和Eclipse integrated development environments,文件共享程序如LimeWire和Vuze. Java還被應用於線性代數計算編程環境,包括用戶界面和部分系統核心功能。
Java ME在移動設備上愈來愈流行,並開始與Symbian, BREW,和.NET Compact Framework展開競爭。
由於手機制造商的多樣性,須要一種新的統一標準,使程序能夠運行於不一樣手機供應商製造的手機上。第一代這樣的標準是MIDP 1,它假設手機顯示屏很小,沒有音頻操做權限,並且只容許小於32kb的程序運行。MIDP2有聲音訪問權限,程序大小限制提升到了64kb。隨着手機設 計的能力和速度的快速提高,其發展速度遠比標準的制定快的多,一些廠商開始放鬆了對標準的遵照,好比容許更大的程序在手機上運行。
網絡服務器和企業級應用
Java EE,Java平臺企業版(Java Platform Enterprise Edition),是Sun公司爲企業級應用推出的標準平臺。Java平臺共分爲三個主要版本Java EE、Java SE和Java ME。
Sun公司在1998年發表JDK1.2版本的時候,使用了新名稱Java 2 Platform,即「Java2平臺」,修改後的JDK稱爲Java 2 Platform Software Developing Kit,即J2SDK。並分爲標準版(Standard Edition,J2SE),企業版(Enterprise Edition,J2EE),微型版(MicroEdition,J2ME)。J2EE便由此誕生。
2005年6月,JavaOne大會召開,SUN公司公開Java SE 6。此時,Java的各類版本已經改名以取消其中的數字「2」:J2EE改名爲Java EE, J2SE改名爲Java SE,J2ME改名爲Java ME。
隨着Java技術的發展,J2EE平臺獲得了迅速的發展,成爲Java語言中最活躍的體系之一。現現在,J2EE不只僅是指一種標準平臺,它更多的表達着一種軟件架構和設計思想。