版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
\hJava技術(shù)手冊(第6版)目錄\h第一部分Java介紹\h第1章Java環(huán)境介紹\h1.1Java語言、JVM和生態(tài)系統(tǒng)\h1.1.1Java語言是什么\h1.1.2JVM是什么\h1.1.3Java生態(tài)系統(tǒng)是什么\h1.2Java和JVM簡史\h1.3Java程序的生命周期\h常見問題解答\h1.4Java的安全性\h1.5Java和其他語言比較\h1.5.1Java和C語言比較\h1.5.2Java和C++比較\h1.5.3Java和PHP比較\h1.5.4Java和JavaScript比較\h1.6回應(yīng)對Java的一些批評\h1.6.1過度復(fù)雜\h1.6.2變化慢\h1.6.3性能問題\h1.6.4不安全\h1.6.5太注重企業(yè)\h第2章Java基本句法\h2.1Java程序概覽\h2.2詞法結(jié)構(gòu)\h2.2.1Unicode字符集\h2.2.2區(qū)分大小寫與空白\h2.2.3注釋\h2.2.4保留字\h2.2.5標識符\h2.2.6字面量\h2.2.7標點符號\h2.3基本數(shù)據(jù)類型\h2.3.1布爾類型\h2.3.2字符類型\h2.3.3整數(shù)類型\h2.3.4浮點數(shù)類型\h2.3.5基本類型之間的轉(zhuǎn)換\h2.4表達式和運算符\h2.4.1運算符概述\h2.4.2算術(shù)運算符\h2.4.3字符串連接運算符\h2.4.4遞增和遞減運算符\h2.4.5比較運算符\h2.4.6邏輯運算符\h2.4.7位運算符和位移運算符\h2.4.8賦值運算符\h2.4.9條件運算符\h2.4.10instanceof操作符\h2.4.11特殊運算符\h2.5語句\h2.5.1表達式語句\h2.5.2復(fù)合語句\h2.5.3空語句\h2.5.4標注語句\h2.5.5局部變量聲明語句\h2.5.6if/else語句\h2.5.7switch語句\h2.5.8while語句\h2.5.9do語句\h2.5.10for語句\h2.5.11遍歷語句\h2.5.12break語句\h2.5.13continue語句\h2.5.14return語句\h2.5.15synchronized語句\h2.5.16throw語句\h2.5.17try/catch/finally語句\h2.5.18處理資源的try語句\h2.5.19assert語句\h2.6方法\h2.6.1定義方法\h2.6.2方法修飾符\h2.6.3已檢異常和未檢異常\h2.6.4變長參數(shù)列表\h2.7介紹類和對象\h2.7.1定義類\h2.7.2創(chuàng)建對象\h2.7.3使用對象\h2.7.4對象字面量\h2.7.5lambda表達式\h2.8數(shù)組\h2.8.1數(shù)組的類型\h2.8.2創(chuàng)建和初始化數(shù)組\h2.8.3使用數(shù)組\h2.8.4多維數(shù)組\h2.9引用類型\h2.9.1引用類型與基本類型比較\h2.9.2處理對象和引用副本\h2.9.3比較對象\h2.9.4裝包和拆包轉(zhuǎn)換\h2.10包和Java命名空間\h2.10.1聲明包\h2.10.2全局唯一的包名\h2.10.3導(dǎo)入類型\h2.10.4導(dǎo)入靜態(tài)成員\h2.11Java文件的結(jié)構(gòu)\h2.12定義并運行Java程序\h2.13小結(jié)\h第3章Java面向?qū)ο缶幊蘚h3.1類簡介\h3.1.1面向?qū)ο蟮幕靖拍頫h3.1.2其他引用類型\h3.1.3定義類的句法\h3.2字段和方法\h3.2.1聲明字段的句法\h3.2.2類字段\h3.2.3類方法\h3.2.4實例字段\h3.2.5實例方法\h3.2.6this引用的工作方式\h3.3創(chuàng)建和初始化對象\h3.3.1定義構(gòu)造方法\h3.3.2定義多個構(gòu)造方法\h3.3.3在一個構(gòu)造方法中調(diào)用另一個構(gòu)造方法\h3.3.4字段的默認值和初始化程序\h3.4子類和繼承\(zhòng)h3.4.1擴展類\h3.4.2超類、對象和類層次結(jié)構(gòu)\h3.4.3子類的構(gòu)造方法\h3.4.4構(gòu)造方法鏈和默認構(gòu)造方法\h3.4.5遮蓋超類的字段\h3.4.6覆蓋超類的方法\h3.5數(shù)據(jù)隱藏和封裝\h3.5.1訪問控制\h3.5.2數(shù)據(jù)訪問器方法\h3.6抽象類和方法\h轉(zhuǎn)換引用類型\h3.7修飾符總結(jié)\h第4章Java類型系統(tǒng)\h4.1接口\h4.1.1定義接口\h4.1.2擴展接口\h4.1.3實現(xiàn)接口\h4.1.4實現(xiàn)多個接口\h4.1.5默認方法\h4.1.6標記接口\h4.2Java泛型\h4.2.1介紹泛型\h4.2.2泛型和類型參數(shù)\h4.2.3菱形句法\h4.2.4類型擦除\h4.2.5通配符\h4.2.6編譯時和運行時類型\h4.3枚舉和注解\h4.3.1枚舉\h4.3.2注解\h4.3.3自定義注解\h4.3.4類型注解\h4.4嵌套類型\h4.4.1靜態(tài)成員類型\h4.4.2非靜態(tài)成員類\h4.4.3局部類\h4.4.4詞法作用域和局部變量\h4.4.5匿名類\h4.4.6嵌套類型的運作方式\h4.5lambda表達式\h4.5.1轉(zhuǎn)換lambda表達式\h4.5.2方法引用\h4.5.3函數(shù)式編程\h4.6小結(jié)\h第5章Java的面向?qū)ο笤O(shè)計\h5.1Java的值\h5.2java.lang.Object類的重要方法\h5.2.1toString()方法\h5.2.2equals()方法\h5.2.3hashCode()方法\h5.2.4Comparable::compareTo()方法\h5.2.5clone()方法\h5.3面向?qū)ο笤O(shè)計要略\h5.3.1常量\h5.3.2用接口還是抽象類\h5.3.3實例方法還是類方法\h5.3.4合成還是繼承\(zhòng)h5.3.5字段繼承和訪問器\h5.3.6單例\h5.4異常和異常處理\h5.5Java編程的安全性\h第6章Java實現(xiàn)內(nèi)存管理和并發(fā)編程的方式\h6.1Java內(nèi)存管理的基本概念\h6.1.1Java中的內(nèi)存泄露\h6.1.2標記清除算法簡介\h6.1.3基本標記清除算法\h6.2JVM優(yōu)化垃圾回收的方式\h篩選回收\h6.3HotSpot堆\h6.3.1回收老年代\h6.3.2其他回收程序\h6.4終結(jié)機制\h終結(jié)機制的細節(jié)\h6.5Java對并發(fā)編程的支持\h6.5.1線程的生命周期\h6.5.2可見性和可變性\h6.5.3互斥和狀態(tài)保護\h6.5.4volatile關(guān)鍵字\h6.5.5Thread類中有用的方法\h6.6使用線程\h6.7小結(jié)\h第二部分使用Java平臺\h第7章編程和文檔約定\h7.1命名和大小寫約定\h7.2實用的命名方式\h7.3Java文檔注釋\h7.3.1文檔注釋的結(jié)構(gòu)\h7.3.2文檔注釋標簽\h7.3.3行內(nèi)文檔注釋標簽\h7.3.4文檔注釋中的交叉引用\h7.3.5包的文檔注釋\h7.4可移植程序的約定\h第8章使用Java集合\h8.1介紹集合API\h8.1.1Collection接口\h8.1.2Set接口\h8.1.3List接口\h8.1.4Map接口\h8.1.5Queue接口和BlockingQueue接口\h8.1.6實用方法\h8.1.7數(shù)組和輔助方法\h8.2在Java集合框架中使用lambda表達式\h8.2.1函數(shù)式方式\h8.2.2流API\h8.3小結(jié)\h第9章處理常見的數(shù)據(jù)格式\h9.1文本\h9.1.1字符串的特殊句法\h9.1.2字符串的不可變性\h9.1.3正則表達式\h9.2數(shù)字和數(shù)學(xué)運算\h9.2.1Java表示整數(shù)類型的方式\h9.2.2Java中的浮點數(shù)\h9.2.3Java的數(shù)學(xué)函數(shù)標準庫\h9.3在Java8中處理日期和時間\h9.3.1介紹Java8的日期和時間API\h9.3.2查詢\h9.3.3調(diào)節(jié)器\h9.3.4過時的日期和時間API\h9.4小結(jié)\h第10章處理文件和I/O\h10.1Java處理I/O的經(jīng)典方式\h10.1.1文件\h10.1.2流\h10.1.3Reader和Writer類\h10.1.4再次介紹TWR\h10.1.5I/O經(jīng)典處理方式的問題\h10.2Java處理I/O的現(xiàn)代方式\h10.2.1文件\h10.2.2路徑\h10.3NIO中的通道和緩沖區(qū)\h10.3.1ByteBuffer對象\h10.3.2映射字節(jié)緩沖區(qū)\h10.4異步I/O\h10.4.1基于Future接口的方式\h10.4.2基于回調(diào)的方式\h10.4.3監(jiān)視服務(wù)和目錄搜索\h10.5網(wǎng)絡(luò)\h10.5.1HTTP\h10.5.2TCP\h10.5.3IP\h第11章類加載、反射和方法句柄\h11.1類文件、類對象和元數(shù)據(jù)\h11.1.1類對象示例\h11.1.2類對象和元數(shù)據(jù)\h11.2類加載的各個階段\h11.2.1加載\h11.2.2驗證\h11.2.3準備和解析\h11.2.4初始化\h11.3安全的編程和類加載\h11.4應(yīng)用類加載知識\h類加載程序?qū)哟谓Y(jié)構(gòu)\h11.5反射\h11.5.1什么時候使用反射\h11.5.2如何使用反射\h11.6動態(tài)代理\h11.7方法句柄\h11.7.1MethodType對象\h11.7.2方法查找\h11.7.3調(diào)用方法句柄\h第12章Nashorn\h12.1介紹Nashorn\h12.1.1在JVM中運行Java之外的語言\h12.1.2目的\h12.2在Nashorn中執(zhí)行JavaScript代碼\h12.2.1在命令行中運行\(zhòng)h12.2.2使用Nashornshell\h12.2.3在jjs中編寫腳本\h12.3Nashorn和javax.script包\h通過javax.script包使用Nashorn\h12.4Nashorn的高級用法\h12.4.1在Nashorn中調(diào)用Java代碼\h12.4.2Nashorn對JavaScript語言所做的擴展\h12.4.3實現(xiàn)細節(jié)\h12.5小結(jié)\hAvatar項目\h第13章平臺工具和配置\h13.1命令行工具\h13.1.1javac\h13.1.2java\h13.1.3jar\h13.1.4javadoc\h13.1.5jdeps\h13.1.6jps\h13.1.7jstat\h13.1.8jstatd\h13.1.9jinfo\h13.1.10jstack\h13.1.11jmap\h13.1.12javap\h13.2VisualVM\h13.3Java8配置\h13.3.1目的\h13.3.2緊湊配置\h13.4小結(jié)注:原文檔電子版(非掃描),需要的請下載本文檔后留言謝謝。第一部分Java介紹第一部分介紹Java語言和Java平臺,其中各章提供了足夠的信息,以便你立即開始使用Java。第1章Java環(huán)境介紹第2章Java基本句法第3章Java面向?qū)ο缶幊痰?章Java類型系統(tǒng)第5章Java的面向?qū)ο笤O(shè)計第6章Java實現(xiàn)內(nèi)存管理和并發(fā)編程的方式第1章Java環(huán)境介紹歡迎學(xué)習(xí)Java8。也許應(yīng)該說歡迎你回來。你可能是從其他語言轉(zhuǎn)到這個生態(tài)系統(tǒng)的,也可能這是你學(xué)習(xí)的第一門編程語言。不管你是如何到達這里的,都要歡迎你。很高興你選擇了Java。Java是一個強大且通用的編程環(huán)境,是世界上使用范圍最廣的編程語言之一,在商務(wù)和企業(yè)計算領(lǐng)域取得了極大的成功。本章介紹Java語言(供程序員編寫應(yīng)用)、Java虛擬機(用來運行應(yīng)用)和Java生態(tài)系統(tǒng)(為開發(fā)團隊提供很多有價值的編程環(huán)境)。我們會先簡要介紹Java語言和虛擬機的歷史,然后說明Java程序的生命周期,最后厘清Java和其他環(huán)境之間一些常見的疑問。本章最后會介紹Java的安全性,還會討論一些安全編程相關(guān)的話題。1.1Java語言、JVM和生態(tài)系統(tǒng)Java編程環(huán)境出現(xiàn)于20世紀90年代末,由Java語言和運行時組成。運行時也叫Java虛擬機(JavaVirtualMachine,JVM)。Java剛出現(xiàn)時,這種分離方式很新奇,但最近軟件開發(fā)的趨勢表明,這已經(jīng)變成了通用做法。值得一提的是微軟的.NET環(huán)境,它比Java晚幾年出現(xiàn),但沿用了非常類似的平臺架構(gòu)方式。微軟的.NET平臺和Java相比有個重要的區(qū)別,人們都覺得Java是相對開放的生態(tài)系統(tǒng),有多個開發(fā)方。在Java的演進過程中,這些開發(fā)方在合作的同時也有競爭,不斷推進Java的技術(shù)發(fā)展。Java成功的主要原因之一是,整個生態(tài)系統(tǒng)是個標準的環(huán)境。這意味著組成Java環(huán)境的各種技術(shù)都有規(guī)范。這些標準讓開發(fā)者和客戶相信,自己所用的技術(shù)能和其他組件兼容,即便來自不同的技術(shù)提供方也不怕。Java目前歸甲骨文公司所有(甲骨文收購了發(fā)明Java的太陽計算機系統(tǒng)公司,以下簡稱Sun)。紅帽、IBM、惠普、SAP、蘋果和富士通等公司也大量參與了Java標準技術(shù)的實現(xiàn)。Java也有開源版本,叫OpenJDK,由多家公司合作開發(fā)。其實,Java由多個不同但相互聯(lián)系的環(huán)境和規(guī)范組成,包括Java移動版(JavaME)、Java標準版(JavaSE)和Java企業(yè)版(JavaEE)。本書只涵蓋JavaSE第8版。后面會詳細說明標準,現(xiàn)在先介紹Java語言和JVM。這是兩個不同但互有關(guān)聯(lián)的概念。1.1.1Java語言是什么Java程序的源碼使用Java語言編寫。Java是人類可讀的編程語言,基于類,而且面向?qū)ο?,比較易讀易寫(偶爾有點啰嗦)。Java有意識地降低了教、學(xué)成本,參考了C++等語言的行業(yè)經(jīng)驗,盡量刪除了復(fù)雜的功能,但保留了“前輩”編程語言的精粹??偟膩碚f,Java的目的是為企業(yè)開發(fā)商業(yè)應(yīng)用提供堅實穩(wěn)定的基礎(chǔ)。作為一門編程語言,Java的設(shè)計相對保守,而且改動頻率低。這么做是有意保護企業(yè)對Java技術(shù)的投入。Java語言自1996年發(fā)布之后,一直在不斷地修訂(但沒有完全重寫)。也就是說,一開始為Java選擇的設(shè)計方式,即20世紀90年代末采用的那些權(quán)宜之計,現(xiàn)在仍舊影響著這門語言。詳情參見第2章和第3章。Java8的變動幅度很大,是近十年來罕見的(有些人覺得是Java出現(xiàn)以來最大的變動)。lambda表達式的引入和核心中集合API的大幅度改寫等,將徹底改變大多數(shù)Java開發(fā)者編寫代碼的方式。Java語言受Java語言規(guī)范(JavaLanguageSpecification,JLS)的約束,這個規(guī)范限定了某項功能必須采用某種方式實現(xiàn)。1.1.2JVM是什么JVM是一個程序,提供了運行Java程序所需的運行時環(huán)境。如果某個硬件和操作系統(tǒng)平臺沒有相應(yīng)的JVM,就不能運行Java程序。幸好,JVM被移植到了大多數(shù)設(shè)備中,機頂盒、藍光播放器、大型機或許都有適用的JVM。Java程序一般都在命令行中啟動,例如:java<arguments><programname>這個命令會在操作系統(tǒng)的一個進程中啟動JVM,提供Java運行時環(huán)境,然后在剛啟動的(空)虛擬機中運行指定的程序。有一點很重要,你要知道:提供給JVM運行的程序不是Java語言源碼,源碼必須轉(zhuǎn)換(或編譯)成一種稱為Java字節(jié)碼的格式。提供給JVM的Java字節(jié)碼必須是類文件格式,其擴展名為.class。JVM是字節(jié)碼格式程序的解釋器,一次只執(zhí)行字節(jié)碼中的一個指令。而且,你還要知道,JVM和用戶提供的程序都能派生額外的線程,所以用戶提供的程序中可能同時運行著多個不同的函數(shù)。JVM的設(shè)計方式建立在幾個早期編程環(huán)境的多年發(fā)展經(jīng)驗之上,尤其是C和C++,因此有多個目的,這些目的都是為了減輕程序員的負擔(dān)。包含一個容器,讓應(yīng)用代碼在其中運行。較之C/C++,提供了一個安全的執(zhí)行環(huán)境。代開發(fā)者管理內(nèi)存。提供一個跨平臺的執(zhí)行環(huán)境。介紹JVM時往往都會提到這些目的。前面介紹JVM和字節(jié)碼解釋器時已經(jīng)提到了第一個目的,即JVM是應(yīng)用代碼的容器。第6章介紹Java環(huán)境如何管理內(nèi)存時會討論第二個和第三個目的。第四個目的有時也說成“一次編寫,到處運行”,意思是Java類文件可從一個運行平臺遷移到另一個平臺,只要有可用的JVM,就能正常運行。也就是說,Java程序可以在運行著OSX的蘋果Mac電腦中開發(fā)(并轉(zhuǎn)換成類文件),然后把類文件移到Linux或微軟Windows(或其他平臺)中,無需任何改動,Java程序依然能運行。Java環(huán)境被移植到了眾多平臺中,除了Linux、Mac和Windows等主流平臺外,還支持很多其他平臺。本書使用“大多數(shù)實現(xiàn)”來概括大多數(shù)開發(fā)者能接觸到的平臺。Mac、Windows、Linux、Solaris、BSDUnix和AIX等被視為“主流平臺”,都算在“大多數(shù)實現(xiàn)”的范圍之內(nèi)。除了上述四個主要目的之外,JVM還有一個設(shè)計方面的考量很少被提及和討論,即JVM使用運行時信息進行自我管理。20世紀70年代和80年代對軟件的研究表明,程序運行時的行為有很多有趣且有用的模式無法在編譯時推論得出。JVM是真正意義上第一個利用這項研究結(jié)果的主流平臺。JVM會收集運行時信息,從而對如何執(zhí)行代碼做出更好的決定。也就是說,JVM能監(jiān)控并優(yōu)化運行在其中的程序,而沒有這種能力的平臺則做不到這一點。一個典型的例子是,在運行Java程序的生命周期中,各組成部分被調(diào)用的次數(shù)并不都是相同的,有些部分調(diào)用的次數(shù)遠比其他部分多得多。Java平臺使用一種名為JIT編譯(just-in-timecompilation)的技術(shù)解決這個問題。在HotSpotJVM(Sun為Java1.3開發(fā)的JVM,現(xiàn)在仍在使用)中,JVM首先識別程序的哪一部分調(diào)用最頻繁(這一部分叫“熱點方法”),然后跳過JVM解釋器,直接把這一部分編譯成機器碼。JVM利用可用的運行時信息,讓程序的性能比純粹經(jīng)解釋器執(zhí)行更高。事實上,很多情況下,JVM使用的優(yōu)化措施得到的性能提升,已經(jīng)超過了編譯后的C和C++代碼。描述JVM必須怎樣運行的標準叫JVM規(guī)范。1.1.3Java生態(tài)系統(tǒng)是什么Java語言易于學(xué)習(xí),而且和其他編程語言相比,擁有的抽象更少。JVM為Java語言(或其他語言)的運行提供了堅實的基礎(chǔ),并且它寫出的程序性能高且是可移植的。這兩種相互聯(lián)系的技術(shù)放在一起,可以讓企業(yè)放心選擇在何處下力發(fā)展。然而,Java的優(yōu)勢不止于此。自Java初期開始,就形成了范圍極廣的生態(tài)系統(tǒng),里面有大量的第三方庫和組件。也就是說,開發(fā)團隊能從現(xiàn)有的連接器和驅(qū)動器中獲益良多,從中他們能獲得幾乎任何能想到的技術(shù),有些收費,有些則開源。在當下的技術(shù)生態(tài)系統(tǒng)中,很少出現(xiàn)某個技術(shù)組件不提供Java連接器的情況。不管是傳統(tǒng)的關(guān)系數(shù)據(jù)庫,還是NoSQL,或者各種企業(yè)級監(jiān)控系統(tǒng)和消息系統(tǒng),都能集成到Java中。這些正是企業(yè)和大型公司采用Java技術(shù)的主要驅(qū)動力。使用現(xiàn)有的庫和組件能釋放開發(fā)團隊的潛能,讓開發(fā)者作出更好的選擇,利用Java核心技術(shù)實現(xiàn)最佳的開放式架構(gòu)。1.2Java和JVM簡史Java1.0(1996年)這是Java的第一個公開發(fā)行版,只包含212個類,分別放在八個包中。Java平臺始終關(guān)注向后兼容性,所以使用Java1.0編寫的代碼,不用修改或者重新編譯,依舊能在最新的Java8中運行。Java1.1(1997年)這一版Java平臺是原來的兩倍多,并且引入了“內(nèi)部類”和第一版反射API。Java1.2(1998年)這是Java一個非常重要的版本。這一版Java平臺是原來的三倍,而且首次出現(xiàn)了集合API(包括Set、Map和List)。1.2版增加的新功能過多,Sun不得不把平臺重新命名為“Java2Platform”。這里的“Java2”是商標,而不是真實的版本號。Java1.3(2000年)這其實是個維護版本,主要用于修正缺陷,解決穩(wěn)定性,并提升性能。這一版還引入了HotSpotJava虛擬機,這個虛擬機現(xiàn)在還在使用(不過有大量的修改和改進)。Java1.4(2002年)這也是一個重要的版本,增加了一些重要的功能,例如高性能低層I/OAPI、處理文本的正則表達式、XML和XSLT庫、SSL支持、日志API和加密支持。Java5(2004年)這一版Java更新幅度很大,對核心語言做了很多改動,引入了泛型、枚舉類型(enum)、注解、變長參數(shù)方法、自動裝包和新版for循環(huán)。改動的量非常大,所以不得不修改主版本號,以新的主版本號發(fā)布。這一版包含3562個類和接口,分別放在166個包中。在增加的內(nèi)容中,值得一提的有并發(fā)編程的實用工具、遠程管理框架和類,以及Java虛擬機本身的監(jiān)測程序。Java6(2006年)這一版也主要是維護和提升性能,引入了編譯器API,擴展了注解的用法和適用范圍,還提供了綁定,允許腳本語言和Java交互。這一版還對JVM和SwingGUI技術(shù)進行了缺陷修正和改進。Java7(2011年)這是甲骨文公司接管Java后發(fā)布的第一個版本,包含語言和平臺的多項重要升級。這一版引入了處理資源的try語句和NIO.2API,讓開發(fā)者編寫的資源和I/O處理代碼更安全且不易出錯。方法句柄API是反射API的替代品,更簡單也更安全,而且打開了動態(tài)調(diào)用(invokedynamic)的大門(Java1.0之后第一種新字節(jié)碼)。Java8(2014年)這是最新版Java,變動的幅度是自Java5(甚至可能是自Java出現(xiàn))以來最大的一次。這一版引入的lambda表達式有望顯著提升開發(fā)者的效率;集合API也升級了,改用lambda實現(xiàn),為此,Java的面向?qū)ο髮崿F(xiàn)方式也發(fā)生了根本性變化。其他重要更新包括:實現(xiàn)運行在JVM中的JavaScript(Nashorn),新的日期和時間支持,以及Java配置(用于生成不同版本的Java,尤其適合部署無界面或服務(wù)器應(yīng)用)。1.3Java程序的生命周期為了更好地理解Java代碼是怎么編譯和執(zhí)行的,以及Java和其他編程環(huán)境的區(qū)別,請看圖1-1中的流程圖。圖1-1:Java代碼是怎么編譯和加載的整個流程從Java源碼開始,經(jīng)過javac程序處理后得到類文件,這個文件中保存的是編譯源碼后得到的Java字節(jié)碼。類文件是Java平臺能處理的最小功能單位,也是把新代碼傳給運行中程序的唯一方式。新的類文件通過類加載機制載入虛擬機(有關(guān)類加載機制更詳細的說明參見第10章),從而把新類型提供給解釋器執(zhí)行。常見問題解答本節(jié)解答一些關(guān)于Java和在Java環(huán)境中編寫的程序的生命周期的最常見問題。1.字節(jié)碼是什么開發(fā)者首次接觸JVM時,可能認為它是“電腦中的電腦”,然后順其自然把字節(jié)碼理解為“內(nèi)部電腦中CPU執(zhí)行的機器碼”或“虛擬處理器執(zhí)行的機器碼”。其實,字節(jié)碼和運行于硬件處理器中的機器碼不太一樣。計算機科學(xué)家視字節(jié)碼為一種“中間表現(xiàn)形式”,處在源碼和機器碼之間。字節(jié)碼的目的是,提供一種能讓JVM解釋器高效執(zhí)行的格式。2.javac是編譯器嗎編譯器一般生成機器碼,而javac生成的是和機器碼不太一樣的字節(jié)碼。不過,類文件有點像對象文件(例如Windows中的.dll文件,或Unix中的.so文件),人類肯定讀不懂。在計算機科學(xué)理論的術(shù)語中,javac非常像編譯器的“前半部分”,它生成的中間表現(xiàn)形式可以進一步處理,生成機器碼。不過,因為類文件的生成是構(gòu)建過程中單獨的一步,類似于C/C++中的編譯,所以很多開發(fā)者都把運行javac的操作稱為編譯。在本書里,我們使用術(shù)語“源碼編譯器”或“javac編譯器”表示生成類文件的javac。我們把“編譯”看作一個單獨的術(shù)語,表示JIT編譯,因為只有JIT編譯才會生成機器碼。3.為什么叫“字節(jié)碼”指令碼(操作碼)只占一個字節(jié)(有些操作還可以有參數(shù),即跟隨其后的字節(jié)流),所以只有256個可用的指令。實際上,有些指令用不到,大概只會使用200個,而且其中還有一些是最新版javac不支持的。4.字節(jié)碼是優(yōu)化過的嗎Java平臺的早期階段,javac會對生成的字節(jié)碼進行大量優(yōu)化。后來表明這么做是錯的。JIT編譯出現(xiàn)后,重要的方法會被編譯成運行速度很快的機器碼。之所以要減輕JIT編譯器的負擔(dān),是因為JIT編譯獲得的效果,比字節(jié)碼優(yōu)化多很多,而且字節(jié)碼還要經(jīng)過解釋器處理。5.字節(jié)碼真的與設(shè)備無關(guān)嗎?那字節(jié)順序呢不管在哪種設(shè)備中生成,字節(jié)碼的格式都是一樣的,其中也包括設(shè)備使用的字節(jié)順序。如果你想知道,我告訴你,字節(jié)碼始終使用大字節(jié)序(big-endian)。6.Java是解釋性語言嗎JVM基本上算是解釋器(通過JIT編譯大幅提升性能)。可是,大多數(shù)解釋性語言(例如PHP、Perl、Ruby和Python)都直接從源碼解釋程序(一般會從輸入的源碼文件中構(gòu)建一個抽象句法樹)。而JVM解釋器需要的是類文件,因此當然需要多一步操作,即使用javac編譯源碼。7.其他語言可以在JVM中運行嗎可以。JVM可以運行任何有效的類文件,因此,Java之外的語言可以通過兩種方式在JVM中運行。第一種,提供用于生成類文件的源碼編譯器(類似于javac),以類似Java代碼的方式在JVM中運行(Scala等語言采用的是這種方式)。Java之外的語言可以使用Java實現(xiàn)解釋器和運行時,然后解釋該語言使用的源碼格式。JRuby等語言采用的就是這種方式(不過JRuby的運行時很復(fù)雜,某些情況下能輔助JIT編譯)。1.4Java的安全性Java的設(shè)計始終考慮安全性,因此和很多其他現(xiàn)有系統(tǒng)和平臺相比有很大的優(yōu)勢。Java的安全架構(gòu)由安全專家設(shè)計,而且這個平臺發(fā)布之后,很多其他安全專家仍在研究和探討。專家們一致認為,Java的安全架構(gòu)堅固牢靠,在設(shè)計層面沒有任何安全漏洞(至少還沒有發(fā)現(xiàn))。Java安全模型的基礎(chǔ)是,嚴格限制字節(jié)碼能表述的操作,例如,不能直接訪問內(nèi)存,因此避免了困擾C和C++等語言的一整類安全問題。而且,只要JVM加載了不信任的類,就會執(zhí)行字節(jié)碼校驗操作,從而避免了大量問題(字節(jié)碼校驗的更多信息,參見第10章)。盡管如此,沒有任何系統(tǒng)能保證100%的安全性,Java也不例外。雖然從理論上講,設(shè)計是牢固的,但安全架構(gòu)的實現(xiàn)是另外一回事,在某些Java實現(xiàn)中,一直都在發(fā)現(xiàn)和修補安全缺陷。不得不說,Java8的延期發(fā)布,至少部分原因是發(fā)現(xiàn)了一些安全問題,必須要投入時間進行修復(fù)。我相信,在實現(xiàn)Java虛擬機的過程中始終都會發(fā)現(xiàn)(并修正)安全缺陷。不過,值得注意的是,最近發(fā)現(xiàn)的Java安全問題大都與桌面技術(shù)有密切聯(lián)系。在日常的服務(wù)器端編程方面,Java仍是當前最安全的通用平臺。1.5Java和其他語言比較本節(jié)簡要列出Java平臺和其他你可能熟悉的編程環(huán)境之間的重要不同點。1.5.1Java和C語言比較Java面向?qū)ο螅珻面向過程。Java通過類文件實現(xiàn)可移植性,C需要重新編譯。Java為運行時提供了全面的監(jiān)測程序。Java沒有指針,也沒有指針相等性運算。Java通過垃圾回收提供了自動內(nèi)存管理功能。Java無法從低層布局內(nèi)存(沒有結(jié)構(gòu)體)。Java沒有預(yù)處理器。1.5.2Java和C++比較Java的對象模型比C++簡單。Java默認使用虛分派(virtualdispatch)。Java始終使用值傳遞(不過Java中的值也能作為對象引用)。Java不完全支持多重繼承。Java的泛型沒C++的模板強大(不過危害性較?。?。Java無法重載運算符。1.5.3Java和PHP比較Java是靜態(tài)類型語言,PHP是動態(tài)類型語言。Java有JIT,PHP沒有(PHP6可能會有)。Java是通用語言,PHP在網(wǎng)站技術(shù)之外很難見到。Java支持多線程,PHP不支持。1.5.4Java和JavaScript比較Java是靜態(tài)類型語言,JavaScript是動態(tài)類型語言。Java使用基于類的對象,JavaScript使用基于原型的對象。Java提供了良好的對象封裝,JavaScript沒有提供。Java有命名空間,JavaScript沒有。Java支持多線程,JavaScript不支持。1.6回應(yīng)對Java的一些批評Java出現(xiàn)在公共視線中已有很長一段時間了,因此,在這些年里受到的批評也相當多。這些批評可以歸咎于一些技術(shù)缺點,以及第一版過度的市場推廣。不過,有些批評只是技術(shù)圈的傳言,不是很準確。本節(jié),我們來看一些常見的抱怨,以及它們在最新版Java平臺中的狀況。1.6.1過度復(fù)雜人們經(jīng)常批評Java核心語言過度復(fù)雜。即便是Objecto=newObject();這樣簡單的語句,也有重復(fù)——賦值符號左右兩邊都出現(xiàn)了類型Object。批評人士認為這么做完全是多余的,其他語言都不需要重復(fù)聲明類型,而且很多輔助功能都不用這么做(例如類型推導(dǎo))。這樣的說法我不認同。從一開始,Java的設(shè)計目標就是易于閱讀(讀代碼的次數(shù)比寫代碼多很多),許多程序員,尤其是新手,都覺得額外的類型信息有助于閱讀代碼。Java廣泛用于企業(yè)環(huán)境,開發(fā)團隊往往和運維團隊不同。這些額外的信息一般會在處理停機,或者需要維護和修訂早就投身其他事務(wù)的開發(fā)者編寫的代碼時提供重大幫助。在最近幾個Java版本中(7和后面的版本),語言的設(shè)計者已經(jīng)在嘗試回應(yīng)這些觀點,他們尋找可以簡化句法復(fù)雜度的地方,也更充分地利用類型信息。例如://文件輔助方法byte[]contents=Files.readAllBytes(Paths.get("/home/ben/myFile.bin"));//使用菱形句法表示重復(fù)的類型信息List<String>l=newArrayList<>();//lambda表達式,簡化了RunnableExecutorServicethreadPool=Executors.newScheduledThreadPool(2);threadPool.submit(()->{System.out.println("OnThreadpool");});然而,Java的總體原則是非常緩慢且謹慎地修改語言,所以這些變化可能無法完全讓批評者滿意。1.6.2變化慢Java第一版發(fā)布至今已經(jīng)超過15年了,而且在那個時候也沒經(jīng)過完整修訂。在這段時間里,很多其他語言(例如微軟的C#)都發(fā)布了不向后兼容的版本,而Java沒這么做,因此受到了部分開發(fā)者的批評。而且,最近幾年,Java語言因為沒有及時吸收其他語言中常見的功能而受到嚴厲批評。Sun(現(xiàn)在是甲骨文)在語言設(shè)計上采取了保守方式,是為了盡量避免把成本和不合理功能的外部效應(yīng)強加在大量的用戶群體身上。很多使用Java的公司都為這一技術(shù)注入了重資,語言設(shè)計者要認真負責(zé),不能影響現(xiàn)有的用戶和安裝群體。每一個新語言功能都要審慎考慮,不只是新功能本身,還要考慮它會如何影響語言現(xiàn)有的功能。有時,新功能的影響會超過目及之處,而Java的使用范圍又如此廣泛,因此可能有很多地方會產(chǎn)生意料之外的影響。功能發(fā)布后,如果有問題,幾乎無法將其刪除。Java有一些不合理的功能(例如終結(jié)機制),在不影響安裝群體的情況下,根本無法安全地刪除。語言設(shè)計者認為,在語言演進的過程中必須極為小心。話雖如此,但Java8引入的新語言功能向前邁出了一大步,回應(yīng)了最常見的功能缺失抱怨,應(yīng)該能為開發(fā)者提供他們一直訴求的語言特性。1.6.3性能問題現(xiàn)在仍然有人批評Java平臺的速度慢,而且所有批評都集中在“平臺”上,這或許是最不合理的批評了。Java1.3引入了HotSpot虛擬機和JIT編譯器,而且在隨后的15年里,一直在革新和改進虛擬機及其性能?,F(xiàn)在,Java平臺的速度異???,經(jīng)常會在流行的框架性能評測中取勝,甚至打敗了編譯成本地機器碼的C和C++。針對這方面的批評大都是因為陳舊的記憶,因為以前的某段時間Java很慢。Java使用的大型且不規(guī)則延展的架構(gòu)方式可能也加深了人們對性能低下的印象。然而,事實上,任何大型架構(gòu)都需要評測、分析和性能調(diào)校,才能得到最好的表現(xiàn),Java也不例外。Java平臺的核心(Java語言和JVM)不僅現(xiàn)在是,以后也仍將是開發(fā)者可用的速度最快的通用環(huán)境。1.6.4不安全2013年,Java平臺出現(xiàn)了幾個安全漏洞,導(dǎo)致Java8的發(fā)布日期延后了。其實,在此之前就有人批評Java的安全漏洞數(shù)量眾多。在這些漏洞中,有很多都涉及Java系統(tǒng)的桌面和GUI組件,不會影響使用Java編寫的網(wǎng)站或其他服務(wù)器端代碼。所有編程平臺都會時不時地出現(xiàn)安全問題,而且很多其他語言的安全漏洞不比Java少,只是少有人知罷了。1.6.5太注重企業(yè)Java平臺在公司和企業(yè)的開發(fā)者中使用廣泛,因此覺得Java太注重企業(yè)一點也不奇怪。人們認為Java缺少面向社區(qū)的語言所具有的自由風(fēng)格。其實,Java一直都是,而且以后仍將是社區(qū)和免費或開源軟件開發(fā)所廣泛使用的語言。在GitHub和其他項目托管網(wǎng)站中,Java是最受歡迎的。而且,使用范圍最廣的Java語言是通過OpenJDK實現(xiàn)的。而OpenJDK本身就是開源項目,其社區(qū)充滿活力,一直在不斷增長。第2章Java基本句法本章簡練而全面地介紹Java句法,主要針對之前有些編程經(jīng)驗但剛接觸這門語言的讀者,對完全沒有編程經(jīng)驗的新手也有一些幫助。如果已經(jīng)了解Java,可以把這一章當成語言參考。為了方便學(xué)過其他編程語言的讀者,本章還對Java與C和C++進行了比較。本章先介紹非常低層的Java句法,然后以此為基礎(chǔ),介紹高級結(jié)構(gòu)。本章包含以下內(nèi)容。編寫Java程序的字符,以及這些字符的編碼。組成Java程序的字面量、標識符和其他標記。Java能處理的數(shù)據(jù)類型。在Java中把單獨的標記放在一起組成復(fù)雜表達式的運算符。語句:把表達式和其他語句放在一起組成Java代碼邏輯塊。方法:一系列Java語句,有名字,可被其他Java代碼調(diào)用。類:由一系列方法和字段組合而成。類是Java程序的核心元素,也是面向?qū)ο缶幊痰幕A(chǔ)。第3章專門介紹類和對象。包:由一系列相關(guān)的類組合而成。Java程序:由一個或多個交互的類組成,這些類可能來自一個或多個包。大多數(shù)編程語言的句法都很復(fù)雜,Java也不例外。一般來說,介紹一門語言的某些元素時,難免會提到一些尚未接觸的元素。例如,介紹Java支持的運算符和語句時,不可避免地要提到對象;類似地,介紹對象時也不能不提Java的運算符和語句。在學(xué)習(xí)Java或任何其他語言的過程中,都要這樣交叉學(xué)習(xí)。2.1Java程序概覽在詳細介紹Java句法之前,我們先花點兒時間概述Java程序。Java程序由一個或多個Java源碼文件(或叫編譯單元)組成。本章末尾會介紹Java文件的結(jié)構(gòu),并且會講解如何編譯和運行Java程序。每個編譯單元都以可選的package聲明開始,后面跟著零個或多個import聲明。這些聲明指定一個命名空間,編譯單元中定義的名稱都在這個命名空間里,而且還指定了編譯單元從哪些命名空間中導(dǎo)入名稱。2.10節(jié)會介紹package和import聲明。在可選的package和import聲明之后,是零個或多個引用類型定義。第3章和第4章會介紹各種可用的引用類型,現(xiàn)在你只需要知道,這些往往都是class或interface定義。在引用類型的定義體中有一些成員,例如字段、方法和構(gòu)造方法。其中,方法是最重要的成員類型。方法是一段由語句組成的Java代碼。了解這些基本術(shù)語之后,下面開始詳細介紹Java程序的基本句法單元。句法單元經(jīng)常被稱為詞法標記(lexicaltoken)。2.2詞法結(jié)構(gòu)本節(jié)說明Java程序的詞法結(jié)構(gòu),首先介紹編寫Java程序的Unicode字符集,然后介紹組成Java程序的標記,包括注釋、標識符、保留字和字面量等。2.2.1Unicode字符集Java程序使用Unicode字符編寫。在Java程序中,任何地方都能使用Unicode字符,包括注釋和標識符,例如變量名。7位ASCII字符集只對英語有用,8位ISOLatin-1字符集只對大多數(shù)西歐語言有用,而Unicode字符集能表示世界上幾乎所有常用的書寫語言。如果使用不支持Unicode的文本編輯器,或者不想強制查看或編輯你代碼的程序員使用支持Unicode的編輯器,你可以使用特殊的Unicode轉(zhuǎn)義序列\(zhòng)uxxxx,把Unicode字符嵌入Java程序。Unicode轉(zhuǎn)義序列由反斜線、小寫的字母u和四個十六進制字符組成。例如,\u0020是空格,\u03c0是字符π。Java投入了大量時間和工程努力,確保能最好地支持Unicode。如果業(yè)務(wù)應(yīng)用面向全球用戶,特別是西方之外的市場,Java平臺是很好的選擇。2.2.2區(qū)分大小寫與空白Java語言區(qū)分大小寫,關(guān)鍵字使用小寫,而且必須這么用;也就是說,While和WHILE與while關(guān)鍵字不是一回事。類似地,如果在程序中把變量命名為i,就不能使用I引用這個變量。一般來說,通過大小寫來區(qū)分標識符是非常糟糕的主意。在代碼中不要這么做,尤其不要使用和關(guān)鍵字同名但大小寫不同的標識符。Java會忽略空格、制表符、換行符和其他空白,除非這些符號出現(xiàn)在引號或字符串字面量中。為了易讀,程序員一般會使用空白格式化和縮進代碼。本書的示例代碼會使用一些常用的縮進約定。2.2.3注釋注釋是使用自然語言編寫的文本,供某一程序的人類讀者閱讀。Java編譯器會忽略注釋。Java支持三種注釋。第一種是單行注釋,以//字符開始,直到行尾結(jié)束。例如:inti=0;//初始化循環(huán)變量第二種是多行注釋,以/*字符開始,不管有多少行,直到*/字符結(jié)束。javac會忽略/*和*/之間的所有文本。雖然這種形式一般用于多行注釋,但也可以用于單行注釋。這種注釋不能嵌套,即/**/中不能再有/**/。編寫多行注釋時,程序員經(jīng)常使用額外的*字符,突出注釋的內(nèi)容。下面是個典型的多行注釋:/**首先,連接服務(wù)器。*如果嘗試連接失敗,立即退出。*/第三種注釋是第二種的一個特例。如果注釋以/**開頭,會被當成特殊的文檔注釋。和普通的多行注釋一樣,文檔注釋也以*/結(jié)尾,而且不能嵌套。如果你編寫了一個Java類,希望讓其他程序員使用,可以直接在源碼中嵌入關(guān)于這個類和其中每個方法的文檔。名為javadoc的程序會提取這些文檔,經(jīng)過處理后生成這個類的在線文檔。文檔注釋中可以包含HTML標簽和javadoc能理解的其他句法。例如:/***把文件上傳到Web服務(wù)器中。**@paramfile要上傳的文件。*@return<tt>true</tt>表示上傳成功,*<tt>false</tt>表示上傳失敗。*@authorDavidFlanagan*/第7章會詳細介紹文檔注釋的句法,第13章會詳細介紹javadoc程序。注釋可以出現(xiàn)在Java程序中的任何標記之間,但不能出現(xiàn)在標記中。注釋尤其不能出現(xiàn)在雙引號字符串字面量中。字符串字面量中的注釋就是這個字符串的一部分。2.2.4保留字以下是Java的保留字(它們是Java語言句法的一部分,不能用來命名變量和類等):abstractconstfinalintpublicthrowassertcontinuefinallyinterfacereturnthrowsbooleandefaultfloatlongshorttransientbreakdofornativestatictruebytedoublegotonewstrictfptrycaseelseifnullsupervoidcatchenumimplementspackageswitchvolatilecharextendsimportprivatesynchronizedwhileclassfalseinstanceofprotectedthis后文還會見到這些保留字,其中有些是基本類型的名稱,有些是Java語句的名稱,這兩種保留字稍后都會進行介紹。還有一些用于定義類和成員,第3章會介紹。注意,雖然Java語言不使用const和goto,但它們也是保留字;interface還有另外一種形式——@interface,用來定義注解類型。有些保留字(尤其是final和default)根據(jù)不同的上下文有不同的意義。2.2.5標識符標識符就是Java程序中某個部分的名稱,例如類、類中的方法和方法中聲明的變量。標識符的長度不限,可以包含Unicode字符集中的任意字母和數(shù)字,但是不能以數(shù)字開頭。一般來說,標識符不能包含標點符號,不過可以包含ASCII字符集中的下劃線(_)和美元符號($),以及Unicode字符集中的其他貨幣符號,例如£和¥。貨幣符號主要用在自動生成的源碼中,例如javac生成的代碼。不在標識符中使用貨幣符號,可以避免自己的標識符和自動生成的標識符沖突。按照規(guī)定,可以出現(xiàn)在標識符開頭和之中的字符由java.lang.Character類中的isJavaIdentifierStart()和isJavaIdentifierPart()方法定義。以下是合法標識符示例:ix1theCurrentTimethe_current_time獺特別注意,其中有個UTF-8標識符——獺。這是一個漢字,英文是“otter”,完全是個合法的Java標識符。在主要是由西方人編寫的程序中不常見到使用非ASCII字符的標識符,但偶爾也有。2.2.6字面量字面量是直接出現(xiàn)在Java源碼中的值,包括整數(shù)、浮點數(shù)、單引號中的單個字符、雙引號中的字符串,以及保留字true、false和null。例如,以下都是字面量:11.0'1'"one"truefalsenull2.3節(jié)會詳細介紹表示數(shù)字、字符和字符串字面量的句法。2.2.7標點符號Java標記中也有一些是標點符號。Java語言規(guī)范把這些字符分成兩類(有點隨意):分隔符和運算符。分隔符有12個:(){}[]...@::;,.運算符如下:+-*/%&|^<<>>>>>+=-=*=/=%=&=|=^=<<=>>=>>>====!=<<=>>=!~&&||++--?:->整本書中都會見到分隔符,2.4節(jié)會分別介紹每個運算符。2.3基本數(shù)據(jù)類型Java支持八種基本數(shù)據(jù)類型,包括一種布爾類型、一種字符類型、四種整數(shù)類型和兩種浮點數(shù)類型,如表2-1所示。四種整數(shù)類型和兩種浮點數(shù)類型的區(qū)別在于位數(shù)不同,因此能表示的數(shù)字范圍也不同。表2-1:Java的基本數(shù)據(jù)類型類型取值默認值大小范圍booleantrue或falsefalse1位NAcharUnicode字符\u000016位\u0000~\uFFFFbyte有符號的整數(shù)08位-128~127short有符號的整數(shù)016位-32768~32767int有符號的整數(shù)032位-2147483648~2147483647long有符號的整數(shù)064位-9223372036854775808~9223372036854775807floatIEEE754浮點數(shù)0.032位1.4E-45~3.4028235E+38doubleIEEE754浮點數(shù)0.064位4.9E-324~1.7976931348623157E+308下面幾節(jié)簡要介紹這些基本數(shù)據(jù)類型。除了基本數(shù)據(jù)類型之外,Java還支持稱為引用類型的非基本數(shù)據(jù)類型,2.9節(jié)會介紹。2.3.1布爾類型布爾類型(boolean)表示真值,只有兩個可選值,表示兩種邏輯狀態(tài):開或關(guān),是或否,真或假。Java使用保留字true和false表示這兩個布爾值。從其他編程語言,尤其是JavaScript,轉(zhuǎn)到Java的程序員要注意,Java比其他語言對布爾值的要求嚴格得多:布爾類型既不是整數(shù)類型也不是對象類型,而且不能使用不兼容的值代替布爾類型。也就是說,在Java中不能使用下面的簡寫形式:Objecto=newObject();inti=1;if(o){while(i){//...}}相反,Java強制要求編寫簡潔的代碼,明確表明想做什么比較:if(o!=null){while(i!=0){//...}}2.3.2字符類型字符類型(char)表示Unicode字符。Java使用一種稍微獨特的方式表示字符:在傳給javac的輸入中,標識符使用UTF-8編碼(一種變長編碼方式),但在內(nèi)部使用定長編碼(16位)表示字符。不過,開發(fā)者一般無需擔(dān)心這個區(qū)別。大多數(shù)情況下,只需記住,如果想在Java程序中使用字符字面量,只需把字符放在單引號中即可:charc='A';當然,字符字面量可以使用任何一個Unicode字符,也可以使用Unicode轉(zhuǎn)義序列\(zhòng)u。而且,Java還支持一些其他轉(zhuǎn)義序列,用來表示常用的非打印ASCII字符,例如換行符以及轉(zhuǎn)義Java中某些有特殊意義的標點符號。例如:chartab='\t',nul='\000',aleph='\u05D0',slash='\\';表2-2列出了可在字符字面量中使用的轉(zhuǎn)義字符。這些字符也可以在字符串字面量中使用,下一節(jié)會介紹。表2-2:Java轉(zhuǎn)義字符轉(zhuǎn)義序列字符值\b退格符\t水平制表符\n換行符\f換頁符\r回車符\"雙引號\'單引號\\反斜線\xxxxxx編碼的Latin-1字符,其中xxx是八進制數(shù),介于000到377之間。\x和\xx兩種形式也是合法的,例如\0,但不推薦這么用,因為轉(zhuǎn)義序列只有一個數(shù)字,在字符串常量中會導(dǎo)致歧義。這種用法在\uxxxx中也不鼓勵使用\uxxxxxxxx編碼的Unicode字符,其中xxxx是四個十六進制數(shù)。Unicode轉(zhuǎn)義序列可以出現(xiàn)在Java程序的任意位置,而不只局限于字符和字符串字面量字符可以轉(zhuǎn)換成整數(shù)類型,也可以從整數(shù)類型轉(zhuǎn)換而來。字符類型對應(yīng)的是16位整數(shù)類型。字符類型與byte、short、int和long不同,沒有符號。Character類定義了一些有用的靜態(tài)方法(staticmethod),用于處理字符,例如isDigit()、isJavaLetter()、isLowerCase()和toUpperCase()。設(shè)計Java語言和字符類型時考慮到了Unicode。Unicode標準一直在發(fā)展,每一個Java新版本都會使用最新版Unicode。Java7使用的是Unicode6.0,Java8使用的是Unicode6.2。最近的幾版Unicode收錄了16位編碼(或叫碼位,codepoint)無法容納的字符。這些追加的字符是十分少見的漢字象形文字,占用了21位,無法使用單個字符表示,必須使用int類型表示,或者必須使用“代理對”(surrogatepair)通過兩個字符表示。除非經(jīng)常使用亞洲語言編寫程序,否則很少會遇到這些追加的字符。如果預(yù)計要處理無法使用單個字符類型表示的字符,就可以使用Character和String等相關(guān)類中提供的方法,使用int類型表示碼位,然后再處理文本。字符串字面量除了字符類型之外,Java還有一種用于處理字符串的數(shù)據(jù)類型。不過,String類型是類,不是基本類型。因為字符串很常用,所以Java提供了一種句法,可以直接在程序中插入字符串。字符串字面量是包含在雙引號中的任意文本(字符字面量使用單引號)。例如:"Hello,world""'This'isastring!"字符串字面量中可以包含能在字符字面量中使用的任何一個轉(zhuǎn)義序列(參見表2-2)。如果想在字符串字面量中插入雙引號,可以使用\"轉(zhuǎn)義序列。String是引用類型,本章后面的2.7.4節(jié)還會深入介紹字符串字面量。第9章會更詳細地介紹在Java中處理String對象的一些方式。2.3.3整數(shù)類型Java中的整數(shù)類型有byte、short、int和long四種。如表2-1所示,這四種類型之間唯一的區(qū)別是位數(shù),即能表示的數(shù)字范圍有所不同。所有整數(shù)類型都表示有符號的數(shù)字,Java沒有C和C++中的unsigned關(guān)鍵字。這四種類型的字面量形式正如你設(shè)想的那樣,使用十進制數(shù)字,前面還可以加上負號。1下面是一些合法的整數(shù)字面量:1嚴格來說,負號是作用在字面量上的運算符,而不是字面量的一部分。01123-42000整數(shù)字面量還可以使用十六進制、二進制和八進制形式來表示。以0x或0X開頭的字面量是十六進制數(shù),使用字母A到F(或a到f)表示數(shù)字的十六進制形式。整數(shù)字面量的二進制形式以0b開頭,當然,只能使用數(shù)字1或0。字面量的二進制形式可能很長,所以經(jīng)常在字面量中使用下劃線。在任何數(shù)字字面量中,下劃線都會被忽略。下劃線純粹是為了提升字面量的可讀性。Java還支持使用八進制表示整數(shù)字面量,以0開頭,而且不能使用數(shù)字8或9。這種字面量不常用,除非有必要,否則應(yīng)該避免使用。下面是一些合法的十六進制、二進制和八進制字面量:0xff//使用十六進制表示的十進制數(shù)2550377//使用八進制表示的十進制數(shù)2550b0010_1111//使用二進制表示的十進制數(shù)470xCAFEBABE//用來識別Java類文件的魔法數(shù)整數(shù)字面量是32位int類型,如果以L或l結(jié)尾,就表示64位long類型:1234//int類型1234L//long類型0xffL//還是long類型在Java中,如果整數(shù)運算超出了指定整數(shù)類型的范圍,不會上溢或下溢,而是直接回繞。例如:byteb1=127,b2=1;//byte類型的最大值是127bytesum=(byte)(b1+b2);//加法運算的結(jié)果直接回繞到-128,即byte類型的最小值如果發(fā)生了這種情況,Java編譯器和解釋器都不會發(fā)出任何形式的警告。進行整數(shù)運算時,必須確保使用的類型取值范圍能滿足計算需要。整數(shù)除以零,或者計算除以零后得到的余數(shù),都是非法操作,會拋出ArithmeticException異常。每一種整數(shù)類型都有對應(yīng)的包裝類:Byte、Short、Integer和Long。這些類都定義了MIN_VALUE和MAX_VALUE常量,表示相應(yīng)的取值范圍。而且還定義了一些有用的靜態(tài)方法,例如Byte.parseByte()和Integer.parseInt(),作用是把字符串轉(zhuǎn)換成整數(shù)。2.3.4浮點數(shù)類型在Java中,實數(shù)使用float和double數(shù)據(jù)類型表示。如表2-1所示,float類型是32位單精度浮點數(shù),double是64位雙精度浮點數(shù)。這兩種類型都符合IEEE754-1985標準。這個標準規(guī)定了浮點數(shù)的格式和運算方式。浮點數(shù)可以以字面量形式插入Java程序,其格式為一些可選的數(shù)字,后跟一個小數(shù)點和一些數(shù)字。下面是幾個示例:123.450.0.01浮點數(shù)字面量還可以使用指數(shù)形式(也叫科學(xué)記數(shù)法)表示,其格式為一個數(shù)后面跟著字母e或E和一個數(shù)。第二個數(shù)表示10的次方,是第一個數(shù)的乘數(shù)。例如:1.2345E02//1.2345*10^2或123.451e-6//1*10^-6或0.0000016.02e23//阿伏加德羅常數(shù):6.02*10^23默認情況下,浮點數(shù)是double類型。若想在程序中插入float類型的字面量,要在數(shù)字后面加上f或F:doubled=6.02E23;floatf=6.02e23f;浮點數(shù)字面量不能使用十六進制、二進制或八進制表示。浮點數(shù)表示的值由于本質(zhì)上的限制,大多數(shù)實數(shù)都不能使用有限的位數(shù)進行精確表示。因此,要記住,float和double類型都只能表示實際值的近似值。float類型是32位近似值,至少有6個有效數(shù)字;double是64位近似值,至少有15個有效數(shù)字。第9章會更詳細地說明浮點數(shù)表示的值。除了表示普通的數(shù)字之外,float和double類型還能表示四個特殊的值:正無窮大、負無窮大、零和NaN。如果浮點數(shù)運算的結(jié)果超出了float或double能表示的范圍上限,得到的是無窮大。如果浮點數(shù)的運算結(jié)果超出了float或double能表示的范圍下限,得到的是零。Java的浮點類型區(qū)分正零和負零,具體是哪個值取決于從哪個方向出現(xiàn)的下溢。在實際使用中,正零和負零的表現(xiàn)基本一樣。最后一種特殊的浮點數(shù)NaN,是“Not-a-Number”的簡稱,表示“不是數(shù)字”。如果浮點數(shù)運算不合法,例如0.0/0.0,得到的就是NaN。以下幾個例子得到的結(jié)果就是這些特殊的值:doubleinf=1.0/0.0;//無窮大doubleneginf=-1.0/0.0;//負無窮大doublenegzero=-1.0/inf;//負零doubleNaN=0.0/0.0;//NaNJava浮點數(shù)類型能處理到無窮大的上溢以及到零的下溢,因此浮點數(shù)運算從不拋出異常,就算執(zhí)行非法運算也沒事,例如零除以零,或計算負數(shù)的平方根。float和double基本類型都有對應(yīng)的類,分別為Float和Double。這兩個類都定義了一些有用的常量:MIN_VALUE、MAX_VALUE、NEGATIVE_INFINITY、POSITIVE_INFINITY和NaN。無窮大浮點數(shù)的表現(xiàn)和設(shè)想的一樣,例如,無窮大之間的加減運算得到的還是無窮大。負零的表現(xiàn)幾乎和正零一樣,而且事實上,相等運算符==會告訴你,負零和正零是相等的。區(qū)分負零、正零和普通的零有一種方法——把它作為被除數(shù):1.0/0.0得到的是正無窮大,但是1.0除以負零得到的是負無窮大。因為NaN不是數(shù)字,所以==運算符會告訴我們它不等于任何其他數(shù)字,甚至包括它自己。若想檢查某個float或double值是否為NaN,必須使用Float.isNaN()或Double.isNaN()方法。2.3.5基本類型之間的轉(zhuǎn)換Java允許整數(shù)和浮點數(shù)之間相互轉(zhuǎn)換。而且,由于每個字符都對應(yīng)Unicode編碼中的一個數(shù)字,所以字符與整數(shù)和浮點數(shù)之間也可以相互轉(zhuǎn)換。其實,在Java中,布爾值是唯一一種不能和其他基本類型之間相互轉(zhuǎn)換的基本類型。類型轉(zhuǎn)換有兩種基本方式。把某種類型的值轉(zhuǎn)換成取值范圍更廣的類型,此時執(zhí)行的是放大轉(zhuǎn)換(wideningconversion)。例如,把int字面量賦值給double類型的變量和把字符字面量賦值給int類型的變量時,Java會執(zhí)行放大轉(zhuǎn)換。另一種方式是縮小轉(zhuǎn)換(narrowingconversion)。把一個值轉(zhuǎn)換成取值范圍沒那么廣的類型時執(zhí)行的就是縮小轉(zhuǎn)換??s小轉(zhuǎn)換并不總是安全的,例如把整數(shù)13轉(zhuǎn)換成byte類型是合理的,但把13000轉(zhuǎn)換成byte類型就不合理,因為byte類型只能介于-128和127之間??s小轉(zhuǎn)換可能丟失數(shù)據(jù),所以試圖縮小轉(zhuǎn)換時Java編譯器會發(fā)出警告,就算轉(zhuǎn)換后的值能落在更窄的取值范圍內(nèi)也會警告:inti=13;byteb=i;//編譯器不允許這么做不過有個例外,如果整數(shù)字面量(int類型)的值落在byte和short類型的取值范圍內(nèi),就能把這個字面量賦值給byte或short類型的變量。如果需要執(zhí)行縮小轉(zhuǎn)換,而且確信這么做不會丟失數(shù)據(jù)或精度,可以使用一種稱為“校正”(cast)的語言結(jié)構(gòu)強制Java轉(zhuǎn)換。若想執(zhí)行類型校正,可以在想轉(zhuǎn)換的值前面加一個括號,在括號里寫上希望轉(zhuǎn)換成哪種類型。例如:inti=13;byteb=(byte)i;//把int類型強制轉(zhuǎn)換成byte類型i=(int)13.456;//把double字面量強制轉(zhuǎn)換成int類型,得到的是13基本類型的校正最常用于把浮點數(shù)轉(zhuǎn)換成整數(shù)。執(zhí)行這種轉(zhuǎn)換時,浮點數(shù)的小數(shù)部分會被直接截掉,即浮點數(shù)向零而不是臨近的整數(shù)舍入。靜態(tài)方法Math.round()、Math.floor()和Math.ceil()執(zhí)行的是另一些舍入方式。大多數(shù)情況下,字符類型的表現(xiàn)都和整數(shù)類型類似,所以需要int或long類型的地方都可以使用字符。不過,還記得嗎,字符類型沒有符號,所以即便字符和short類型都是16位,表現(xiàn)上也有差異:shorts=(short)0xffff;//這些比特表示數(shù)字-1charc='\uffff';//還是這些比特,表示一個Unicode字符inti1=s;//把short類型轉(zhuǎn)換成int類型,得到的是-1inti2=c;//把字符轉(zhuǎn)換成int類型,得到的是65535表2-3列出了各種基本類型能轉(zhuǎn)換成何種其他類型,以及轉(zhuǎn)換的方式。其中,字母N表示無法轉(zhuǎn)換;字母Y表示放大轉(zhuǎn)換,由Java自動隱式轉(zhuǎn)換;字母C表示縮小轉(zhuǎn)換,需要顯式校正。最后,Y*表示自動執(zhí)行的放大轉(zhuǎn)換,但在轉(zhuǎn)換過程中最低有效位可能丟失。把int或long類型轉(zhuǎn)換成浮點類型時可能會出現(xiàn)這種情況,詳情參見下表。浮點類型的取值范圍比整數(shù)類型廣,所以int或long類型都能用float或double類型來表示。然而,浮點類型是近似值,所以有效數(shù)字不一定總與整數(shù)類型一樣多(浮點數(shù)的詳細介紹參見第9章)。表2-3:Java基本類型轉(zhuǎn)換基本類型轉(zhuǎn)換為booleanbyteshortcharintlongfloatdoubleboolean-NNNNNNNbyteN-YCYYYYshortNC-CYYYYcharNCC-YYYYintNCCC-YY\*YlongNCCCC-Y\*Y\*floatNCCCCC-YdoubleNCCCCCC-2.4表達式和運算符到目前為止,我們學(xué)習(xí)了Java程序能處理的基本類型,以及如何在Java程序中使用基本類型的字面量。還使用了變量作為值的符號名稱。字面量和變量都是組成Java程序的標記。表達式是Java程序更高一級的結(jié)構(gòu)。Java解釋器會求出表達式的值。最簡單的表達式叫基本表達式,由字面量和變量組成。例如,下面幾個例子都是表達式:1.7//一個浮點數(shù)字面量true//一個布爾字面量sum//一個變量Java解釋器計算字面量表達式得到的結(jié)果是字面量本身;計算變量表達式得到的結(jié)果是存儲在變量中的值?;颈磉_式?jīng)]什么意思。使用運算符把基本表達式連在一起可以組成復(fù)雜的表達式。例如,下面
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版新型建筑項目施工安全免責(zé)協(xié)議書3篇
- 2025版智慧物流合作投資項目協(xié)議書范本3篇
- 2025年新型環(huán)保材料應(yīng)用個人住宅裝修合同
- 2025年項目合作商業(yè)機密保密協(xié)議書2篇
- 2025年全球及中國低溫硅導(dǎo)熱液行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025年全球及中國核電蒸發(fā)器U型管行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025-2030全球經(jīng)典拉線驅(qū)動探頭行業(yè)調(diào)研及趨勢分析報告
- 2025-2030全球氧化鋯蒸發(fā)材料行業(yè)調(diào)研及趨勢分析報告
- 2025年度個人住房借款合同模板(含二次抵押)3篇
- 2025年度個人二手房交易合同范本解析
- 廣東省茂名市電白區(qū)2024-2025學(xué)年七年級上學(xué)期期末質(zhì)量監(jiān)測生物學(xué)試卷(含答案)
- 2024版?zhèn)€人私有房屋購買合同
- 2024爆炸物運輸安全保障協(xié)議版B版
- 2025年度軍人軍事秘密保護保密協(xié)議與信息安全風(fēng)險評估合同3篇
- 《食品與食品》課件
- 讀書分享會《白夜行》
- 中國服裝零售行業(yè)發(fā)展環(huán)境、市場運行格局及前景研究報告-智研咨詢(2025版)
- 光伏工程施工組織設(shè)計
- DB4101-T 121-2024 類家庭社會工作服務(wù)規(guī)范
- 化學(xué)纖維的鑒別與測試方法考核試卷
- 2024-2025學(xué)年全國中學(xué)生天文知識競賽考試題庫(含答案)
評論
0/150
提交評論