關於Java的誕生和發展網上比較多,在此就再也不贅述了,能夠參考http://i.cnblogs.com/EditArticles.aspx?postid=4050233。html
1995年,Sun雖然推出了Java,但這只是一種語言,若是想開發複雜的應用程序,必需要有一個強大的開發類庫。所以,Sun在1996年初發布了JDK 1.0。這是Sun公司發佈的初版JDK,這個版本包括兩部分:java
JRE 運行環境(Java Runtime Environment):包括核心API、集成API,用戶界面API、發佈技術、Java虛擬機(JVM)。
JDK 開發環境(Java Development Kit):開發環境包括編譯Java程序的編譯器(即javac命令)。linux
接着,Sun在1997年2月18日發佈了JDK 1.1。JDK 1.1增長了JIT(即時編譯)編譯器。JIT和傳統的編譯器不一樣,傳統的編譯器是編譯一條,運行完後將其扔掉。而JIT會將常常用到的指令保存在內存中,當下次調用時就不須要從新編譯了,經過這種方式讓JDK在效率上有了較大提高。程序員
到1998年12月,Sun發佈了Java歷史上最重要的JDK版本:JDK l.2。伴隨JDK l.2一同發佈的還有jsp/servlet3、EJB4(Enterprise JavaBean)等規範,並將Java分紅了J2EE、J2SE和J2ME三個版本。
J2EE 企業版(Java 2 Platform,Enterprise Edition):Java技術中應用最普遍的部分,J2EE提供了企業應用開發相關的完整解決方案。
J2SE 標準版(Java 2 Platform, Simple Edition):整個Java技術的核心和基礎,它是J2ME和J2EE編程的基礎。
J2ME 微縮版(Java Platform,Micro Edition): 主要用於控制移動設備和信息家電等有限存儲的設備。
這標誌着Java已經吹響了向企業、桌面和移動3個領域進軍的號角,標誌着Java已經進入Java 2時代,這個時期也是Java飛速發展的時期。在Java 2中,Java發生了不少革命性的變化,而這些革命性的變化一直沿用到如今,對Java的發展造成了深遠的影響。直到今天,咱們還常常看到J2EE、J2ME等名稱。
不只如此,JDK 1.2還把它的API分紅了三大類:正則表達式
核心API:由Sun公司制定的基本的API,全部的Java平臺都應該提供。這就是咱們日常所說的Java核心類庫。算法
可選API:這是Sun爲JDK提供的擴充API,這些API因平臺的不一樣而不一樣。shell
特殊API:用於知足特殊要求的API。如用於JCA相JCE的第三方加密類庫。編程
2002年2月,Sun發佈了JDK歷史上最爲成熟的版本:JDK l.4.此時因爲Compaq、Fujitsu、SAS、Symbian、IBM等公司的參與,使JDK 1.4成爲發展最快的一個JDK版本。到JDK l.4爲止,咱們已經可使用Java實現大多數的應用了。
在此期間.Java語言在企業應用領域大放異彩,涌現出大量基於Java語言的開源框架:Struts、WebWork、Hibemate、Spring等;大量企業應用服務器也開始涌現:WebLogic、WebSphere、JBoss等,這些都標誌着Java語言進入了飛速發展時期。小程序
2004年10月,Sun發佈了萬衆期待的JDK 1.5,同時,Sun將JDK 1.5更名爲Java SE 5.0。J2EE、J2ME也相應地更名Java EE和Java ME。JDK1.5增長了諸如泛型、加強的for語句、可變數量的形參、註釋(Annotations)、自動拆箱和裝箱等功能;同時,也發佈了新的企業級平臺規範如經過註釋等新特性來簡化EJB的複雜性,並推出了EJB3.0規範。還推出了本身的MVC框架規範:JSF,JSF規範相似於ASP.NET的服務器端控件,經過它能夠快速地構建複雜的JSP界面。windows
2006年l2月.Sun公司發佈手JDK l.6(也被稱爲Java SE 6)。一直以來,Sun公司維持着大約2年發佈一次JDK新版本盼習慣。但在2009年4月20日,Oracle宣佈將以每股9.5美圓韻價格收購Sun。該交易的總價值約爲74億美圓。而Orack經過收購Sun公司得到了兩項軟件資產Java和Solaris。因而曾經表明一個時代的公面:Sun終於被「雨打風吹’’去,「江湖」上再也沒有了Sun的身影。
Sun倒下了,不過Java的大旗依然「獵獵"做響。2007年11月,Google宣佈推出一款基於Linux平臺的開源手機操做系統:Android。Android的出現順應了即將出現的移動互聯網潮流,並且Android系統的用戶體驗很是好,所以迅速成爲手機操做系統的中堅力量。
Ancfioid平臺使用了Dalvik虛擬機來運行.dex文件。
Dalvik虛擬機的做用相似於JVM虛擬機,只是它並未遵照JVM規範而已。
Android使用Java語言來開發應用程序,這也給了Java語言一個新的機會。在過去的歲月中Java語言做爲服務器端編程語言,已經取得了極大盼成勱;而Android平臺的流行,則讓Java謠衰得到了在客戶端程序上大展拳腳的機會。
2011年7月28,Oracle公司終於如約一發布了Java SE 7此次版本。升級通過了將近5年時間。Java SE 7也是Oracle發佈的第一個Java版本。Javat.SE 7雖然並未徹底知足所存人的指望,不過它也加入了很多新特性。
Java語言目前是最流行的面向對象編裎語言,與Java相似的程序設計語言還有C#、Ruby和Python等,它們在某些方面有本身的獨特優點,所以都是Java語言有力的競爭者。
當年Microsoft也一度加入到Java語言陣營中,Microsoft曾經在Visual Studio中提供了Visual J++。正當Microsoft盡力在Visual J++基礎上拓展Java功能,並使之與Windows操做系統緊密結合在一塊兒時.Sun公司對Nticrosoft提出法律訴訟,稱其違反了Java許可證協議中的條款,最終的結果是微軟公司不得不中止Visual J++-產品的開發。
1998年10月以來,Microsoft就再也不發佈新的Visual J++版本,並且致使Microsoft一直站在Java陣營的對立面,甚至在Windows XP系統中再也不提供Java運行時環境的支持。接下來,Microson推出了.NET平臺,併發布了C#語言,不管從哪一個角度來看,C#程序設計語言都是Microsoft對Java語言的反擊。自C#誕生之日起,關於C#與Java之間的論戰便此起彼伏,至今不輟。
相同點:
(1) 從技術的角度來看
C#與Java是對傳統面向對象程序設計在組件化軟件時代的革新成果,可謂異曲同工,兩種編程語言甚至有90%的重疊。Java和C撐都對傳統C++-艱深、晦澀的語法和語義進行了改進。
(2) 在語法方面
二者都摒棄了C++中函數及其參數的const修飾、宏代換、全局變量和全局函數等華而不實的地方;
(3) 在繼承方面
二者都採用了更易於理解的單繼承和多接口的實現方案;
(4) 在源代碼組織方面
都提出了聲明與實現於雖體的邏輯封裝。
不一樣點:
C#也有其獨特的優點:Microsoft提供的Visual Studio開發平臺能夠極好地提升C#程序的開發效率,並且Microsoft要比Java更善於利用Windows平臺,當使用C#建立Windows服務、記錄Windows事件日誌、訪問Windows註冊表時,.NET確實更方便。Microsof提供了Windows任務相關的大量基類,容許程序員經過嚮導、拖放等操做來快速開發應用所以比較容易使用。
Java的設計宗旨獨立於任何平臺,天然不會提供太多的Windows特性。但這也正是Java語言的優點:跨平臺。對於一個企業應用而言,永遠沒法肯定這個應用須要在怎樣的平臺上運行,若是你一旦選擇了c撐語言,那麼你的應用就只能侷限在Windows平臺上。所以,對於一個開放式的企業應用而言,一般會選擇Java做爲開發語言,而不是選擇C#。
Ruby語言由日本人松本行弘於1993年起開始着手研發,經歷2年時間,發佈了Ruby語言的第一個版本:0.95版。據松本行弘的描述:他一直想發明一種語言,這種語言既能進行高效開發,又能讓開發人員享受編程的快樂。
事實上,Ruby確實是一種很是簡潔的解釋型語言1,一種純粹的面向對象編程語言。甚至比Java更純粹(在Java語言裏,還有基本數據類型等不是對象的變量,但在Ruby語言裏,一切都是對象)。除此以外,Ruby還提供了許多額外的便捷功能,好比閉包、迭代和集合等,這些都是爲了達到Ruby語言刨始人的夢想:讓Ruby開發者能享受編程的快樂。
Ruby語言最大的特徵就是簡潔:
首先,它是一種弱類型的語言,變量無須聲明,變量沒有類型,所以Ruby的變量能夠保存任何類型的數據:
其次,它還提供了強大的正則表達式支持,並支持運算符重載;
除此,Ruby也提供了許多額外的便捷功能,好比閉包、代碼塊、迭代器和集合等。
Ruby語言還有一個重要的優勢:它也是徹底跨平臺的,能夠在任何操做系統上解釋執行。
2004年,Ruby語言陣營裏出現了一個優秀的MVC框架:Ruby On Rails,這個開發框架被宣傳成現有企業框架的一個替代品。Ruby On Rails框架是一個真正意義上的敏捷開發框架,它提供了大量代碼生成器,經過使用這些代碼生成器能夠極好地提升應用的開發效率。
相對於Java領域的衆多開發框架而言。Ruby on Rails提供了一個「一站式」的解決方案.Ruby On Rails框架提供了Web層的MVC框架、持久層的ORM等解決方案。藉助於Ruby這種動態語言的優點,整個應用的代碼至關簡潔,於是使得Ruby On Rails應用的開發很是快速。關於Rails框架和Java EE平臺,算實是各有優點的。
Python由Guido於1989年年末開發,Python語言是基於ABC教學語言2的。ABC這種語言很是優美和強大,是專門爲非專業程序員設計的.可是.ABC語言並無得到普遍的應用,Guido認爲是非開放形成的。
Guido決心在Python中避免這一錯誤,所以Guido增強了Python和其餘語言如C、C#和Java的結合性。同時,他還實現了許多ABC中閃現過但不曾實現的東西。Python的第一個實現是基於Mac機的。Python由ABC語言發展而來,主要受到了Modula-3(另外一種至關優美且強大的語言,爲小型團體所設計)的影響,而且結合了UNIX shell和C的習慣。
Python是一種面向對象的解釋型編程語言,也是一種功能強大而完善的通用型語言,已經具備十多年的發展歷史,成熟且穩定。Python具備腳本語言中最豐富和強大的類庫,足以支持絕大多很多天常應用。Python語言具備簡潔而清晰的語法特色,適合完成各類高層任務,幾乎能夠在全部的主流操做系統上運行。
雖然Python也是一種解釋型的腳本語言,但一些大規模的軟件開發計劃,好比Zope、Mnet、BitTorrent和Google都普遍地使用了該語言,而Python的支持者喜歡稱它爲高級動態編程語言,所以Python絕非JavaScript等只能處理簡單任務的腳本語言所能比擬的。
Python的兩大特點是可擴展性和清晰的語法。Python新的內置模塊(module)能夠用C或C++寫成,也可爲現成的模塊加上Python-的接口。Python的設計者在設計它的時候認爲:對於一個特定的一問題,只要有一種最好的方法來解決就行了。所以.Python甚至不是一種格式自由的語言.例如.它要求if語句的下一行必須向右縮進,不然不能經過編譯。
Python在編程領域的佔有率一直處於穩步上升之中根據最新的數據,Python排名第七。前六名分別是Java、C、VB、C++、PHP和Perl。最近,微軟也將Python入.NET平臺,相信Python盼將來會更好。
Java語言是一種特殊的高級語言,它既具備解釋型語言的特徵,也具備編譯型語言的特徵,由於Java程序要通過先編譯,後解釋兩個步驟。
計算機高級語言接程序的執行方式能夠分爲編譯型和解釋型兩種。
(1) 編譯型語言
編譯型語言是指使用專門的編譯器,針對特定平臺(操做系統)將某種高級語言源代碼一次性「翻譯」成可被該平臺硬件執行的機器碼(包括機器指令和操做數),幷包裝成該平臺所能識別的可執行性程序的格式,這個轉換過程稱爲編譯( Compile)。編譯生成的可執行性程序能夠脫離開發環境,在特定的平臺上獨立運行.
有些程序編譯結束後,還可能須要對其餘編譯好的目標代碼進行連接,即組裝兩個以上的目標代碼模塊生成最終的可執行性程序,經過這種方式實現低層次的代碼複用。由於編譯型語言是—次性地編譯成機器碼,因此能夠脫離開發環境獨立運行,並且一般運行效率較高。但由於編譯型語言的程序被編譯成特定平臺上的機器碼,所以編譯生成的可執行性程序一般沒法移植到其餘平臺上運行;若是須要移植,則必須將源代碼複製到特定平臺上,針對特定平臺進行修改,至少也須要採用特定平臺上的編譯器從新編譯。現有的C、C++、FORTRAN、Pascal等高級語言都屬於編譯型語言。
(2) 解釋型語言
解釋型語言是指使用專門的解釋器對源程序逐行解釋成特定平臺的機器碼並當即執行的語言。解釋型語言一般不會進行總體性的編譯和連接處理,解釋型語言至關於把編譯型語言中的編譯和解釋過程混合到一塊兒同時完成。能夠認爲:每次執行解釋型語言的程序都須要進行一次編譯,所以解釋型語言的程序運行效率一般較低,並且不能脫離解釋器獨立運行。但解釋型語言有一個優點:跨平臺比較容易,只需提供特定平合的解釋器便可,每一個特定平臺上的解釋器負責將源程序解釋成特定平臺的機器指令便可。解釋型語言能夠方便地實現源程序級的移植,但這是以犧牲程序執行效率爲代價的。
現有的Ruby、Python等語言都屬於解釋型語言。
除此以外,還有一種僞編譯型語言,如Visual Basic,它屬於半編譯型語言,並非真正的編譯型語言。它首先被編譯成P-代碼,並將解釋引擎封裝在可執行性程序內,當運行程序時P-代碼會被解析成真正的二進制代碼。表面上看起來,Visual Basic能夠編譯生成可執行性的EXE文件,並且這個EXE文件也能夠脫離開發環境,在特定平臺上運行,很是像編譯型語言。實際上,在這個EXE文件中,既有程序的啓動代碼,也有連接解釋程序的代碼,而這部分代碼負責啓動Visual Basic解釋程序,再對Visual Basic代碼進行解釋並執行。
Java語言比較特殊,由Java語言編寫的程序須要通過編譯步驟,但這個編譯步驟並不會生成特定平臺的機器碼,而是生成一種與平臺無關的字節碼(也就是.class文件)。固然,這種字節碼不是可執行性的,必須使用Java解釋器來解釋挾行。所以,咱們能夠認爲:Java語言既是編譯型語言,也是解釋型語言。或者說,Java語言既不是純粹的編譯型語言,也不是純粹的解釋型語言Java程序的執行過程必須通過先編譯,後解釋兩個步驟,如圖所示。
Java語言裏負責解釋執行字節碼文件的是Java虛擬機,即JVM(Java Virtual Machine)。JVM是可運行Java字節碼文件的虛擬計算機。全部平臺上的JVM向編譯器提供相同的編程接口,而編譯器只須要面向虛擬機,生成虛擬機能理解的代碼,而後由虛擬機來解釋執行。在一些虛擬機的實現中,還會將虛擬機代碼轉換成特定系統的機器碼執行,從而提升執行效率。
當使用Java編譯器編譯Java程序時,生成的是與平臺無關的字節碼,這些字節碼不面向任何具體平臺,只面向JVM。不一樣平臺上的JVM都是不一樣的,但它們都提供了相同的接口。JVM是Java程序跨平臺的關鍵部分,只要爲不一樣平臺實現了相應的虛擬機,編譯後的Java字節碼就能夠在該平臺上運行。顯然,相同的字節碼程序須要在不一樣的平臺上運行,這幾乎是「不可能的」,只有經過中間的轉換器才能夠實現,JVM就是這個轉換器。
JVM是一個抽象的計算機,和實際的計算機同樣,它具備指令集並使用不一樣的存儲區域。它負責執行指令,還要管理數據、內存和寄存器。
注意: JVM的做用很容易理解,就像咱們有兩支不一樣的筆,但須要把同一個筆帽套在兩支不一樣的筆上,這就須要爲這兩支筆分別提供一個轉換器。這個轉換器: |
Sun公司制定的Java虛擬機規範,在技術上規定了JVM的統一標準,具體定義了JVM的以下細節:
Sun公司制定這些規範的目的是爲了提供統一的標準,最終實現Java程序的平臺無關性。
在開發Java程序以前,必須先完成一些準備工做,也就是在計算機上安裝並配置Java開發環境,開發Java程序必須配置安裝JDK。
JDK的全稱是Java SE Development Kit,即Java 標準版開發包,是Sun提供的一套用於開發Java應用程序的開發包。它提供了編譯、運行Java程序所需的各類工具和資源,包括Java編譯器、Java行時環境以及經常使用的Java類庫等。
JRE:Java運行時環境,它的全稱是Java Runtime Environment,所以也被稱爲JRE它是運行Java程序的必需條件。
注意: 簡單的說,JRE包含JVM。JVM是運行Java程序的核心虛擬機,而運行Java程序不只須要核心虛擬機,還須要其餘的類加載器、字節碼校驗器以及大量的基礎類庫。JRE除了包含JVM以外,還須要包含運行Java程序的其餘環境的支持。 |
通常而言,若是隻是運行Java程序,咱們只安裝JRE,無需安裝JDk。若是要開發Java程序,則應選擇安裝JDK;固然,安裝了JDK以後,就包 含了JRE,也能夠運行Java程序。但若是隻是運行Java程序,則須要在計算機上安裝JRE。僅安裝JVM是不夠的。實際上,Sun網站上提供的就是 JRE的下載,並不提供單獨的JVM下載。 |
Sun把Java分爲Java SE、Java EE和Java ME三個部分,並且爲Java SE和Java EE分別提供了JDK和Java EE SDK(Software Development Kit)兩個開發包若是你只須要學習Java SE的編程知識,則能夠下載標準的JDK;若是你還須要學習Java EE的相關內容也能夠選擇下載Java EE SDK,有一個Java EE SDK版本里已經包含了最新版的JDK,安裝Java EE SDK就包含了JDK。
下載和安裝步驟以下:
(1) 登錄 http://www.oracle.com/technetwork/java/javase/downloads/index.html頁面,下載Java SE Development Kit的最新版本
(2) 在該頁面中咱們能夠看到JDK不一樣的版本,目前咱們能夠看到,當前的最新版本是JDK 8,點擊以下圖2.1所示的頁面連接,進入JDK 8的下載界面,如圖2.2所示,在該頁面中咱們能夠看到兩種類型的JDK版本,一個是帶「java example」源碼,一個是不帶「java example」源碼的。而且每種類型,針對不一樣操做系統平臺有對應不一樣的JDK版本:
圖 2.1
圖 2.2
(3) 下載完成後:
(4) Linux的安裝方式比較簡單,用tar命令將JDK包解壓,而後配置環境變量便可,不在贅述,能夠參考http://www.cnblogs.com/sunddenly/p/3977809.html。
Windows平臺上安裝JDK的步驟:
1. 雙擊安裝包EXE文件,開始安裝後,第一個對話框提問是否贊成Java的許可協議,單機「接受」按鈕,進入如圖2.3所示的組件界面。
圖 2.3
下面介紹一下JDK中的這些組件:
公共JRE:是一個獨立的JRE系統,會單獨安裝在系統的其餘路徑下。公用JRE會向Internet Explore瀏覽器和系統中註冊Java運行時環境。經過這種方式,系統中任何應用程序均可以使用公用JRE。但大部分時候,並不須要安裝全部組件,在圖2.3中我選擇安裝了兩個組件,沒有安裝公共JRE。因爲如今在網頁上執行Applet的機會愈來愈少了,並且徹底可使用JDK目錄下的JRE來運行Java程序,所以,沒有太大必要安裝公用JRE
Java開發工具:這是JDK的核心,包括編譯java程序的必需命令工具。實際上,這個選項裏已經包含了運行Java程序的JRE了,這個JRE會安裝在JDK目錄的子目錄裏這也是我不安裝公共jre的緣由。
源代碼:安裝這個選項將會安裝java全部核心類庫的源代碼。
(5) 選擇安裝路徑,安裝完成後可在JDK安裝路徑下看到以下文件路徑。
圖 2.4
注意: 用於編譯java程序所使用的javac.exe命令也是用java寫的,這個類就是lib目錄下tool.jar文件中sun\tools\javac路徑下的Main類JDK的bin目錄下的java.exe文件實際上僅僅是包裝了這個java類。不只如此,bin目錄下的絕大部分命令都包裝了tool.jar文件裏的工具類。 |
path環境變量的值是一系列指令的路徑:
在Windows操做系統中,當咱們執行一條命令時,Windows會根據Path環境變量來查找這個命令。若是能找到這個命令,則該命令可執行。不然將出現「‘xxxx’不是內部或外部命令,也不是可運行的程序或批處理文件」的提示。
在Linux操做系統中,Linux也會根據PATH環境變量來查找命令。
由於Windows操做系統不區分大小寫 ,設置path和PATH並無區別;而Linux區分大小寫,設置path和PATH是有區別的,所以只須要設置PATH環境變量便可。
Windows配置方式:
在windows中的配置方式以下圖所示:
(1) 打開計算機,點擊系統屬性。
(2) 點擊高級系統設置
(3) 點擊環境變量
(4) 環境變量有兩種類型,系統變量和用戶變量,我選擇系統變量,在系統變量裏已經有一個Path變量,咱們雙擊它。
(5) 在該窗口的,變量值選項的最後加入:;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
注意: 路徑中'%--%'表示引用操做,JAVA_HOME表示一個系統變量,'%JAVA_HOME%',表示對該變量的引用,但該變量未設置,下面咱們將對其進行設置。 |
(6) 在系統變量欄,點擊新建,新建一個JAVA_HOME變量,變量的值爲jdk的安裝路徑。
(7) 設置CLASSPATH,設置變量值爲:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar,下面會介紹。
注意: 用戶變量和系統變量沒有太大的區別,只是用戶變量只對當前用戶有效,而系統變量對全部用戶有效。爲了減小本身的操做對他人的影響。對於當 前用戶而言,設置用戶變量和系統變量效果大體相同,只是系統變量在用戶變量以前。可能出現這一種狀況:若是Path系統變量的路徑裏包含了java命令而 PATH用戶變量的路徑裏也包含了java命令,則優先執行Path系統變量路徑裏包含的java命令。 |
Linux配置方式:
在 linux 中環境變量的設置方法有如下三種(以PATH爲例):
(1) 直接使用 export 命令
[root@hadoop ~]# export PATH=$PATH:/usr/local/jdk/bin
在Linux中,變量之間的分隔符是「:」Windows中是";",查看是否已經設置好,可使用命令 export 命令來查看,也能夠直接$變量名來查看
[root@hadoop ~]# $PATH
-bash: .:/usr/local/hadoop/bin:/usr/local/zk/bin:/usr/local/zk/conf:/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:
[root@hadoop ~]#
注意: 直接使用 export 設置的變量,都是臨時變量,也就是說退出當前的 shell ,爲該變量定義的值便不會生效了。如何能讓咱們定義的變量永久生效呢,那就看咱們的第二種定義的方式。 |
(2) 修改 /etc/profile
[root@hadoop ~]# vi /etc/profile
export PATH=$PATH:/usr/local/jdk/bin # 在配置文件中加入此行配置
須要注意的是:修改完這個文件必需要使用 如下命令在不用重啓系統的狀況下使修改的內容生效
[root@hadoop ~]# source /etc/profile 或者是:[root@hadoop ~]# . /etc/profile
查看設置是否生效
[root@hadoop ~]# echo $PATH
.:/usr/local/hadoop/bin:/usr/local/zk/bin:/usr/local/zk/conf:/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@hadoop ~]#
配置已經生效
(3) 修改 .bashrc 文件(在當前用戶 shell 下生效)
# vi /root/.bashrc?在裏面加入:
export PATH=$PATH:/usr/local/jdk/bin
修改這個文件以後一樣也須要使用 source 或者是 . 使配置文件生效。再來使用 echo $PATH看下變量是否生效
[root@hadoop ~]# echo $PATH
.:/usr/local/hadoop/bin:/usr/local/zk/bin:/usr/local/zk/conf:/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@hadoop ~]#
export命令參數 功能:設置或顯示環境變量,export的效力僅及於該此登錄操做。 語法:export [-fnp][變量名稱]=[變量設置值] 參數: -f 表明[變量名稱]中爲函數名稱。 -n 刪除指定的變量。變量實際上並未刪除,只是不會輸出到後續指令的執行環境中。 -p 列出全部的shell賦予程序的環境變量。 補充:在shell中執行程序時,shell會提供一組環境變量。 export可新增,修改或刪除環境變量,供後續執行的程序使用。 一個變量建立時,它不會自動地爲在它以後建立的shell進程所知。而命令export能夠向後面的shell傳遞變量的值。當一個shell腳本調用並執行時,它不會自動獲得原爲腳本(調用者)裏定義的變量的訪問權,除非這些變量已經被顯式地設置爲可用。export命令能夠用於傳遞一個或多個變量的值到任何後繼腳本 |
咱們知道,編譯和運行java程序必須通過兩個步驟。
(1) 將源文件編譯成字節碼。
(2) 解釋執行平臺無關字節碼。
上面的兩個步驟分別須要使用java和javac兩個命令。當咱們在操做系統的命令窗口,輸入java和 javac命令,將看到以下提示:
‘java’不是內部或外部命令,也不是可運行的程序或批處理文件
‘javac’不是內部或外部命令,也不是可運行的程序或批處理文件
則說明咱們JDK的Path環境變量沒有配置,須要按照上面的步驟進行配置。
設置完Path環境變量,咱們就可使用這兩個命令來編譯和執行咱們的java程序了。下面在Linux上,以運行一個小程序來分析javac和java的做用
步驟下所示:
[root@hadoop code]# pwd
/usr/code
[root@hadoop code]# vi HelloWorld.java
public class HelloWorld{
public static void main(String args[]){
System.out.println("HelloWorld");
}
}
[root@hadoop code]# javac HelloWorld.java
[root@hadoop code]# ls
HelloWorld.class HelloWorld.java
[root@hadoop code]# java HelloWorld
HelloWorld
由上面的操做可知,咱們的當前路徑是/usr/code,在該路徑下新建一個".java"源文件,編輯文件內容輸入程序代碼。而後通過javac編譯生成".class"平臺無關字節碼,默認名稱爲其中類名,最後由「java 類名」命令來執行該字節碼,輸出最終結果「HelloWorld」。下面咱們輸入javac命令,看一下它的參數:
注意:
當代碼中含有包名的時候,編譯以後,再次是「java 類名」,就會出現錯誤,我新建了一個帶有包名的源文件以下:
[root@hadoop code]# vi PackageTest.java
package build.classes;
public class HelloWorld{
public static void main(String args[]){
System.out.println("HelloWorld");
}
}
[root@hadoop code]# ls
HelloWorld.class HelloWorld.java PackageTest.java
[root@hadoop code]# javac PackageTest.java
[root@hadoop code]# java PackageTest.java
Exception in thread "main" java.lang.NoClassDefFoundError: PackageTest/java
Caused by: java.lang.ClassNotFoundException: PackageTest.java
………………
Could not find the main class: PackageTest.java. Program will exit.
從上面的錯誤提示信息,咱們能夠知道錯誤緣由是找不到PackageTest,其實者這不難理解,既然在代碼中加入了「package build.classes;」這行代碼,就表示了PackageTest這個源文件,是在build/classes路徑下,但是並無該路徑,因此會找不到,並且此時執行的時候不能用「java 類名」而應該是「java 包名.類名」。
因此一種解決方案以下:
[root@hadoop code]# javac -d ./ PackageTest.java
[root@hadoop code]# ls
build HelloWorld.class HelloWorld.java jar.jar PackageTest.class PackageTest.java
[root@hadoop code]# java build.classes.PackageTest
HelloWorld
咱們能夠發現,在執行 javac -d ./ PackageTest.java時會在指定目錄生成相應包名。
另外一種解決方案:感受最簡單,直接把包名刪除,在當前路徑執行javac、java。
關於java和javac的詳細介紹,可參考:
http://www.cnblogs.com/pengxl/archive/2010/12/10/1902082.html
http://www.cnblogs.com/JeffChen/archive/2008/01/16/1041783.html
總結: |
由下圖javac的命令參數可知,classpath選項,主要用來指定用戶類文件。那麼由此可知,環境變量「CLASSPATH」也是用來定位類的,當咱們執行「java 類名時」JRE默認從當前位置搜索「.class」文件,當咱們在系統中設置了CLSSPATH時,就會從CLASSPATH路徑查找「.class」字節碼文件。
所以,只要在咱們的CLASSPATH對應的路徑中有咱們的字節碼文件時,那麼就能夠在任何路徑下經過java命令來執行咱們的「.class」字節碼文件。以下圖所示,在/usr目錄下有一個子目錄,code中有一個子目錄classes,code中存放的是".java"源碼,classes中存放的是「.class」字節碼,這樣咱們就能夠將字節碼目錄的路徑設置爲CLASSPATH,當咱們在任意路徑上,經過「java 類名」來運行java程序。目錄結構以下圖所示,個人CLASSPATH設置的路徑爲:「/usr/code/classess」
|---usr
|---code
|---".java"
|---classes
|---".class"
我以,含有包名「build.classes」的PackageTest.java源碼爲例,對上述進行測試,步驟以下:
[root@hadoop code]#vi PackageTest.java
package build.classes;
public class PackageTest{
public static void main(String args[]){
System.out.println("HelloWorld");
}
}
[root@hadoop code]# ls
PackageTest.java
[root@hadoop code]# javac -d ./classes PackageTest.java
[root@hadoop code]# java build.classes.PackageTest
HelloWorld
我在學習ZooKeeper編程時,打算在Linux系統中,經過javac和java命令來執行一段程序,代碼以下:
須要注意的有兩處:
(1) 程序中須要導入「.jar"包,以下圖所示。
(2) 使用main函數的args參數,以下圖所示。
對應的處理有兩處:
(1) 將ZooKeeper的全部jar包,加入到CLASSPATH,以下圖所示。
(2) 執行「java 類名」時,後面加入對應的參數,即主機號和節點名稱,以下所示。
java org.zk.CreateGroup localhost:2181 zoo1
運行結果:
[root@hadoop code]# ls
build classes CreateGroup.java HelloWorld.java jar.jar PackageTest.java zookeeper.out
[root@hadoop code]# javac -d ./classes CreateGroup.java
[root@hadoop code]# java org.zk.CreateGroup localhost:2181 zoo1
2014-10-28 18:00:26,154 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.5-1392090, built on 09/30/2012
2014-10-28 18:00:26,157 [myid:] - INFO [main:Environment@100] - Client environment:host.name=hadoop
2014-10-28 18:00:26,157 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.6.0_24
2014-10-28 18:00:26,157 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Sun Microsystems Inc.
2014-10-28 18:00:26,158 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/local/jdk/jre
2014-10-28 18:00:26,158 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=.:/usr/local/jdk/lib:……
……
Created:/zoo1
2014-10-28 18:00:26,236 [myid:] - INFO [main:ZooKeeper@684] - Session: 0x4956f7f1d70005 closed
2014-10-28 18:00:26,237 [myid:] - INFO [main-EventThread:ClientCnxn$EventThread@509] - EventThread shut down
[root@hadoop code]#
CLASSPATH環境變量經常設置爲:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar, 咱們知道CLASSPATH做用是,在經過「java 類名」解釋執行java程序時,JRE會去搜索類文件,而CLASSPATH就爲JRE提供了搜索路徑。下面,我對上面的CLASSPATH環境變量作一下解釋:
(1) 引用符和分隔符
在Windows上,分隔符:「;」
引用符:「%……%」
在Linux上, 分隔符:「:」
引用符:「$」
(2) 變量的意義
上面有三個路徑,用兩個分號隔開,它們的意義以下:
1.「.」:
‘點’也表示路徑,他表示的是當前路徑。由於在默認狀況下,咱們會在當前路徑下生成類文件,因此須要把該路徑添加到CLASSPATH環境變量裏
2.「%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar」:
編譯和運行Java程序還須要JDK的lib路徑下的dt.jar和tool.jar文件中的Java類,因此還須要把這兩個文件添加到CLASSPATH環境變量裏。
實際上,若是使用1.5以上版本的JDK,JRE會自動搜索當前路徑下的類文件,並且使用Java編譯和運行工具時系統能夠自動加載dt.jar和tools.jar文件中的Java類,所以即便不設置CLASSPATH環境變量,也能運行java程序。但1.4之前版本的JDK都沒這個功能,這意味着即便當前路徑已經包含了HeIloWorld.class並在當前路徑下執行「java HeIIoWorld",系統將同樣提示找不到HeIIoWorld類。
若是使用更早版本的JDK,一般須要設置CLASSPATH環境變量。若是想在運行Java程序時臨時指定JRE搜索Javtr類的路徑,則可使用-classpath選項,即按以下格式來運行java命令:
java -classpath dirl;dir2,dir3……;dirN Java類
classpath選項的值能夠是一系列的路徑,多個路徑之間在Windows平臺上以分號";"隔開,在LinUX平臺上財以冒號":"隔開。
若是在運行Java程序時指定了-classpath選項的值,JRE將嚴格按-classpath選項所指定的路徑來搜索Java類,即不會在當前路徑下搜索Java類,CLASSPATH環境變量所指定的搜索路徑也再也不有效。
若是想使CLASSPATH環境變量指定的搜索路徑有效,並且還會在當前路徑下搜索Java類,則能夠按以下格式來運行Java程序:
java -classpath %CLASSPATH%;.;dir1;dir2;dir3……;dirN java類
上面命令經過%CLASSPATH%來引用CLASSPATH環境變量的值,並在classpath選項的值裏添加了一點,強制JRE在當前路徑下搜索Java類。
傳統的C/C++等編程語言,須要程序員負責回收已經分配的內存。顯式進行垃圾回收是一件比較困難的事情,由於程序員並不老是知道內存應該什麼時候被釋放。若是一些分配出去的內存得不到及時回收,就會引發系統運行速度降低,甚至致使程序癱瘓,這種現象被稱爲內存泄漏。整體而言,顯式進行垃圾回收主要有以下兩個缺點。
(1) 程序忘記及時回收無用內存,從而致使內存泄漏,下降系統性能。
(2) 程序錯誤地回收程序核心類庫的內存,從而致使系統崩潰。
與C/C++程序不一樣,Java語言不須要程序員直接控制內存回收,Java程序的內存分配和回收都是由JRE在後臺自動進行的。JRE會負責回收那些再也不使用的內存,這種機制被稱爲垃圾回收(GarbageCollection,也被稱爲GC)。一般JRE會提供一個後臺線程來進行檢測和控制,通常都是在CPU空閒或內存不足時自動進行垃圾回收,而程序員沒法精確控制垃圾回收的時間相順序等。
Java的堆內存是一個運行時數據區,用以保存類的實例(對象),Java虛擬機的堆內存中存儲着正在運行的應用程序所創建的全部對象,這些對象不須要程序經過代碼來顯式地釋放。通常來講,堆內存的回收由垃圾回收來負責,全部的JVM實現都有一個由垃圾回收器管理的堆內存。垃圾回收是一種動態存儲管理技術,它自動地釋放再也不被程序引用的對象,按照特定的垃圾回收算法來實現內存資源的自動回收功能。
在C/C++中,對象所佔的內存在程序結束運行以前一直被佔用,被明確釋放以前不能分配給其餘對象;在Java中,當沒有對象引用指向原先分配給某個對象的內存時,該內存便成爲垃圾。JVM的一個超級線程會自動釋放該內存區。垃圾回收意味着程序再也不須要的對象是「垃圾信息」,這些信息將被丟棄。
當一個對象再也不被引用時,內存回收它佔領的空間,以便空間被後來的新對象使用。事實上,除了釋放沒用的對象外,垃圾回收也能夠清除內存記錄碎片。因爲建立對象和垃圾回收器釋放丟棄對象所佔的內存空間,內存會出現碎片。碎片是分配給對象的內存塊之間的空閒內存區,碎片整理將所佔用的堆內存移到堆的一端,JVM將整理出的內存分配給新的對象。
優勢:
垃圾回收能自動稃放內存空間,減輕編程的負擔。這使Java虛擬機具備兩個顯著的優勢。
(1) 垃圾回收機制能夠很好地提升編程效率。
在沒有垃圾回收機制時,可能要花許多時間來解決一個難懂的存儲器問題。在用Java語言編程時,依靠垃圾回收機制可大大縮短期。
(2) 垃圾回收機制保護程序的完整性,垃圾回收是Java語言安全性策略的一個重要部分。
缺點:
垃圾回收的一個潛在缺點是它的開銷影響程序性能。
(1) Java虛擬機必須跟蹤程序中有用的對象,才能夠肯定哪些對象是無用的對象,並最終釋放這些無用的對象。這個過程須要花費處理器的時間。
(2) 垃圾回收算法的不完備性,早先採用的某些垃圾回收算法就不能保證100%收集到全部的廢棄內存。
固然,隨着垃圾回收算法的不斷改進,以及軟硬件運行效率的不斷提高,這些問題均可以迎刃而解。
轉自 http://www.cnblogs.com/sunddenly/p/4050812.html