您可以使用本指南查找和安裝最新的Java仪壮,了解Java發(fā)行版(AdoptOpenJdk秕噪,OpenJDK嫩海,OracleJDK等)之間的差異早抠,以及獲得Java語言功能的概述,包括Java版本8-13碑韵。
Java 8赡茸,Java 11,Java 13 —有什么區(qū)別祝闻?
您可能還會(huì)喜歡:超越Java 8背景資料
首先占卧,讓我們看一下人們?cè)趪L試為其項(xiàng)目選擇正確的Java版本時(shí)遇到的一些常見的實(shí)際問題。
如果要了解有關(guān)特定版本的更多信息联喘,請(qǐng)轉(zhuǎn)到 AdoptOpenJDK 網(wǎng)站华蜒,選擇最新的Java版本,下載并安裝它豁遭。然后回到本指南叭喜,仍然學(xué)習(xí)有關(guān)不同Java版本的一兩個(gè)東西。
我應(yīng)該使用哪個(gè)Java版本蓖谢?
截至2019年9月捂蕴, Java 13 是最新發(fā)布的Java版本,每6個(gè)月更新一次版本-Java 14計(jì)劃在2020年3月發(fā)布蜈抓,Java 15計(jì)劃在2020年9月發(fā)布启绰,依此類推昂儒。在過去沟使,Java的發(fā)布周期 更長(zhǎng),最長(zhǎng)可達(dá)3-5年渊跋!
隨著許多新版本的出現(xiàn)腊嗡,基本上存在以下實(shí)際使用場(chǎng)景:
公司中的舊項(xiàng)目經(jīng)常使用Java 8進(jìn)行阻塞(請(qǐng)參閱下面的“ 為什么公司仍停留在Java 8上着倾?”部分)。因此燕少,您也將不得不使用Java 8卡者。
有些舊項(xiàng)目甚至卡在Java 1.5(2004年發(fā)布)或1.6(2006年發(fā)布)上,對(duì)不起客们,朋友們崇决!
如果您確保使用最新的IDE,框架和構(gòu)建工具并啟動(dòng)新項(xiàng)目底挫,則可以毫不猶豫地使用Java 11(LTS)或最新的Java 13恒傻。
在Android開發(fā)的特殊領(lǐng)域,Java版本基本上停留在Java 7上建邓,并提供了一組 特定的Java 8功能 盈厘。或者官边,您可以切換到使用Kotlin編程語言沸手。
為什么公司仍然堅(jiān)持使用Java 8?
公司仍然堅(jiān)持使用Java 8的原因多種多樣注簿,僅舉幾例:
構(gòu)建工具(Maven契吉,Gradle等)和某些庫(kù) 最初 存在Java版本> 8的錯(cuò)誤,并且需要更新诡渴。即使在今天栅隐,例如使用Java 9+,某些構(gòu)建工具也會(huì) 在構(gòu)建Java項(xiàng)目時(shí)打印出 “反射訪問”警告玩徊,即使構(gòu)建良好租悄,也只是“感覺還沒有準(zhǔn)備好”。
直到Java 8為止恩袱,您幾乎都在使用Oracle的JDK構(gòu)建泣棋,并且您不必在乎許可。但是畔塔,甲骨文在2019年更改了 許可計(jì)劃潭辈,這使Internet瘋狂地說“ Java不再免費(fèi)”了,隨之而來的是相當(dāng)多的混亂澈吨。但是把敢,這并不是真正的問題,您可以在本指南的“ Java發(fā)行版 ”部分中進(jìn)行了解谅辣。
一些公司制定了僅使用LTS版本的政策修赞,并且依靠其OS供應(yīng)商為他們提供這些版本,這需要時(shí)間桑阶。
總結(jié)起來柏副,您會(huì)遇到一系列實(shí)際問題(升級(jí)工具勾邦,庫(kù),框架)和政治問題割择。
為什么某些Java版本稱為1.X眷篇?
9之前的Java版本僅具有不同的命名方案。因此荔泳,Java 8也可以稱為 1.8蕉饼,Java 5也可以稱為 1.5, 依此java -version 類推玛歌。以這些版本發(fā)出 命令時(shí)椎椰,將得到如下輸出:
c:\Program?Files\Java\jdk1.8.0_191\bin>java?-versionjava?version?"1.8.0_191" (1)Java(TM) SE?Runtime?Environment?(build?1.8.0_191-b12)Java?HotSpot(TM) 64-Bit?Server?VM?(build?25.191-b12, mixed?mode)
這只是意味著Java8。隨著Java 9切換到基于時(shí)間的發(fā)行版沾鳄,命名方案也發(fā)生了變化慨飘,并且Java版本不再以1.x作為前綴。現(xiàn)在译荞,版本號(hào)如下所示:
c:\Program Files\Java\jdk11\bin>java -versionopenjdk version?"11"?2018-09-25?(1)OpenJDK Runtime Environment 18.9?(build 11+28)OpenJDK 64-Bit Server VM 18.9?(build 11+28, mixed mode)
Java版本之間有什么區(qū)別瓤的?我應(yīng)該學(xué)習(xí)特定的嗎?
來自其他編程語言吞歼,并且版本之間存在重大差異圈膏,例如Python 2至3,您可能想知道是否同樣適用于Java篙骡。
Java是特別在這方面稽坤,因?yàn)樗欠浅O蚝蠹嫒荨_@意味著您的Java 5或8程序可以保證與Java 8-13虛擬機(jī)一起運(yùn)行-某些例外情況您現(xiàn)在不必?fù)?dān)心糯俗。
顯然尿褪,它反之亦然。例如得湘,您的程序依賴于Java 13功能杖玲,而Java 8 JVM根本無法使用這些功能。
這意味著兩件事:
您不僅可以“學(xué)習(xí)”特定的Java版本淘正,例如Java 12摆马。
而是,直到Java 8為止鸿吆,您都將在所有語言功能方面都有良好的基礎(chǔ)囤采。
然后,您可以從像這樣的指南中了解 Java 9-13附帶了哪些 附加功能惩淳,并盡可能使用它們蕉毯。
Java版本之間這些新功能的示例是什么?
請(qǐng)看下面的“ Java功能8-13 ”部分。
但根據(jù)經(jīng)驗(yàn):較舊恕刘,較長(zhǎng)的發(fā)行周期(3-5年缤谎,直到Java 8)意味著每個(gè)發(fā)行版都有許多新功能抒倚。
六個(gè)月的發(fā)布周期意味著每個(gè)版本的功能會(huì)更少褐着,因此您可以快速掌握J(rèn)ava 9-13語言功能。
JRE和JDK有什么區(qū)別托呕?
到目前為止含蓉,我們僅談?wù)摗?Java”。但是Java 到底是什么项郊?
首先馅扣,您需要區(qū)分 JRE (Java運(yùn)行時(shí)環(huán)境)和 JDK (Java開發(fā)工具包)。
從歷史上看着降, 如果您只對(duì)運(yùn)行Java程序感興趣差油,則僅下載 JRE。JRE包括Java虛擬機(jī)(JVM)和“ java”命令行工具任洞。
要開發(fā)新的Java程序蓄喇,您需要下載 JDK。JDK包含 JRE擁有的所有內(nèi)容交掏,以及編譯器 javac 和其他一些工具妆偏,例如 javadoc (Java文檔生成器)和 jdb (Java Debugger)。
現(xiàn)在為什么我用過去時(shí)說話呢盅弛?
直到Java 8為止钱骂,Oracle網(wǎng)站都將JRE和JDK作為單獨(dú)的下載提供,盡管JDK始終始終在單獨(dú)的文件夾中包含JRE挪鹏。對(duì)于Java 9见秽,這種區(qū)別基本上已經(jīng)消失了,您總是在下載JDK讨盒。JDK的目錄結(jié)構(gòu)也已更改张吉,不再有顯式的JRE文件夾。
因此催植,即使某些發(fā)行版(請(qǐng)參見“ Java發(fā)行版 ”部分)仍提供單獨(dú)的JRE下載肮蛹,似乎也存在僅提供JDK的趨勢(shì)。因此创南, 從現(xiàn)在開始伦忠,我們將交替使用 Java 和 JDK。
然后如何安裝Java或JDK稿辙?
目前昆码,請(qǐng)忽略Java-Docker映像,.msi包裝器或特定于平臺(tái)的軟件包。最后赋咽,Java只是一個(gè).zip文件旧噪。僅此而已。
因此脓匿,將Java安裝到計(jì)算機(jī)上所需要做的就是解壓縮jdk- .zip文件淘钟。您甚至不需要管理員權(quán)限。
您解壓縮后的Java文件如下所示:
Directory?C:\dev\jdk-1112.11.2019??19:24????<DIR> .12.11.2019??19:24????<DIR> ..12.11.2019??19:23????<DIR> bin12.11.2019??19:23????<DIR> conf12.11.2019??19:24????<DIR> include12.11.2019??19:24????<DIR> jmods22.08.2018??19:18????<DIR> legal12.11.2019??19:24????<DIR> lib12.11.2019??19:23?????????????1.238?release
神奇的事情發(fā)生在/ bin目錄下陪毡,在Windows下看起來像這樣:
Directory?C:\dev\jdk-11\bin...12.11.2019??19:23???????????272.736?java.exe...12.11.2019??19:23????????????20.832?javac.exe...
因此米母,您所需要做的就是解壓縮該文件并將/ bin目錄放在PATH變量中,以便可以從任何地方調(diào)用“ java”命令毡琉。
(如果您想知道铁瞒,GUI安裝程序(例如來自O(shè)racle或AdoptOpenJDK的GUI安裝程序)將為您解壓縮并修改PATH變量。
要驗(yàn)證您是否正確安裝了Java桅滋,只需運(yùn)行即可 java -version慧耍。如果輸出看起來像下面的輸出,那就好了丐谋!
openjdk version?"11"?2018-09-25OpenJDK Runtime Environment 18.9?(build 11+28)OpenJDK 64-Bit Server VM 18.9?(build 11+28, mixed mode)v
現(xiàn)在芍碧,還有一個(gè)問題:您從哪里獲得Java .zip文件?這將我們帶到了發(fā)行主題笋鄙。
Java發(fā)行版
有許多提供Java下載的站點(diǎn)(閱讀:JDK)师枣,目前尚不清楚“誰提供什么許可以及哪種許可”。本節(jié)將對(duì)此進(jìn)行一些說明萧落。
OpenJDK項(xiàng)目
在Java源代碼方面(請(qǐng)閱讀:JRE / JDK的源代碼)践美, OpenJDK項(xiàng)目 站點(diǎn) 上 只有一個(gè)。
這只是源代碼找岖,而不是可分發(fā)的內(nèi)部版本(請(qǐng)考慮:您的.zip文件以及針對(duì)特定操作系統(tǒng)的已編譯Java命令)陨倡。從理論上講,您和我可以從該源代碼生成一個(gè)內(nèi)部版本许布,將其 命名為MarcoJDK兴革, 然后開始進(jìn)行分發(fā)。但是我們的發(fā)行版將缺少認(rèn)證蜜唾,無法合法地稱自己為 Java SE兼容杂曲。
這就是為什么在實(shí)踐中,有少數(shù)供應(yīng)商實(shí)際上創(chuàng)建了這些構(gòu)建袁余,并通過了認(rèn)證(請(qǐng)參閱 TCK)擎勘,然后進(jìn)行分發(fā)。
而且颖榜,盡管供應(yīng)商無法在生成新的Java構(gòu)建之前從String類中刪除方法棚饵,但他們可以添加商標(biāo)(是C喝埂)或添加他們認(rèn)為有用的其他實(shí)用程序(例如CLI)。但是除此之外 噪漾,所有 Java發(fā)行版的原始源代碼都是 相同的 硼砰。
OpenJDK構(gòu)建(由Oracle)和OracleJDK構(gòu)建
從源代碼構(gòu)建Java的供應(yīng)商之一是Oracle。這導(dǎo)致了 兩種不同的Java發(fā)行版欣硼,一開始可能會(huì)非程夂玻混亂。
OpenJDK 由Oracle(7直稹)構(gòu)建遍愿。這些版本是免費(fèi)的且沒有商標(biāo)存淫,但是Oracle不會(huì)在Java 14推出后立即發(fā)布Java 13等舊版本的更新耘斩。
OracleJDK是品牌的商業(yè)版本,從2019年許可更改開始桅咆。這意味著它可以在開發(fā)中免費(fèi)使用括授,但是如果在生產(chǎn)中使用Oracle,則需要付費(fèi)岩饼。為此荚虚,您將獲得更長(zhǎng)的支持,即籍茧,如果JVM發(fā)瘋版述,則可以更新版本和電話號(hào)碼。
現(xiàn)在寞冯,從歷史上講(Java 8之前的版本)渴析,OpenJDK構(gòu)建和OracleJDK構(gòu)建之間存在實(shí)際的源差異,您可以說OracleJDK是“更好”的吮龄。但是到今天為止俭茧,這兩個(gè)版本基本上是相同的,只是有 微小的差異漓帚。
采用OpenJDK
2017年母债,一組Java用戶組成員,開發(fā)人員和供應(yīng)商(亞馬遜尝抖,微軟毡们,Pivotal,Red Hat等)創(chuàng)建了一個(gè)名為AdoptOpenJDK的社區(qū) 昧辽。
他們提供免費(fèi)的衙熔,堅(jiān)如磐石的OpenJDK構(gòu)建,具有 更長(zhǎng)的可用性/更新 奴迅,甚至為您提供兩種不同的Java虛擬機(jī)的選擇:HotSpot 和 OpenJ9青责。
我強(qiáng)烈建議 您如果要安裝Java挺据。
Azul Zulu,Amazon Corretto脖隶,SAPMachine
您可以在OpenJDK Wikipedia 站點(diǎn)上找到OpenJDK構(gòu)建的完整列表 扁耐。其中包括 Azul Zulu, Amazon Corretto和 SapMachine等产阱。簡(jiǎn)而言之婉称,歸結(jié)為您擁有不同的支持選項(xiàng)/維護(hù)保證。
但是构蹬,請(qǐng)務(wù)必查看各個(gè)網(wǎng)站王暗,以了解每種發(fā)行版本的優(yōu)勢(shì)。
建議
要從頭開始重申庄敛,除非您有非常特殊的要求俗壹,否則請(qǐng)?jiān)?019年從https://adoptopenjdk.net獲取jdk.zip(.tar.gz / .msi / .pkg)文件 或選擇提供的軟件包由您的操作系統(tǒng)供應(yīng)商提供。
Java功能8-13
如本指南開頭所述:基本上 所有 Java 8語言功能(現(xiàn)在不要挑剔)都可以在Java 13中使用藻烤。這之間的所有其他Java版本也是如此绷雏。
反過來,這意味著Java 8的所有語言功能都可以作為Java的良好基礎(chǔ)知識(shí)怖亭,而其他所有功能(Java 9-13)則是在 該基線之上的許多附加功能 涎显。
以下是必須提供的特定版本的快速概述:
Java 8
Java 8是一個(gè)龐大的版本,您可以在Oracle網(wǎng)站上找到所有功能的列表 兴猩。我想在這里提到兩個(gè)主要功能集:
語言功能:Lambdas等
在Java 8之前期吓,無論何時(shí)要實(shí)例化一個(gè)新的Runnable,都必須編寫一個(gè)匿名內(nèi)部類倾芝,如下所示:
Runnable runnable = new?Runnable(){???????@Override???????public?void?run(){?????????System.out.println("Hello world !");???????}?????};
對(duì)于lambda讨勤,相同的代碼如下所示:
您還獲得了方法參考,重復(fù)注釋蛀醉,接口的默認(rèn)方法以及其他一些語言功能悬襟。
Runnable runnable = ()?->?System.out.println("Hello world two!");
集合和流
在Java 8中,您還獲得了集合的函數(shù)式操作拯刁,也稱為Stream API脊岳。一個(gè)簡(jiǎn)單的例子:
List<String> list?= Arrays.asList("franz", "ferdinand", "fiel", "vom", "pferd");
現(xiàn)在,在Java 8之前的版本中垛玻,您基本上必須編寫for循環(huán)才能對(duì)該列表進(jìn)行處理割捅。
使用Streams API,您可以執(zhí)行以下操作:
list.stream()????.filter(name?-> name.startsWith("f"))????.map(String::toUpperCase)????.sorted()????.forEach(System.out::println);
Java 9
Java 9也是一個(gè)相當(dāng)大的發(fā)行版帚桩,其中增加了一些功能:
集合
集合有幾個(gè)新的輔助方法亿驾,可以輕松地構(gòu)造列表,集合和地圖账嚎。
List<String> list = List.of("one", "two", "three");Set<String> set = Set.of("one", "two", "three");Map<String, String> map = Map.of("foo", "one", "bar", "two");
流
流有幾個(gè)補(bǔ)充莫瞬,在形式 takeWhile儡蔓, dropWhile和 iterate 方法。
Stream<String> stream = Stream.iterate("", s -> s + "s")??.takeWhile(s -> s.length() < 10);
Optionals
Optionals得到了一個(gè)非常不錯(cuò)的 ifPresentOrElse 方法疼邀。
user.ifPresentOrElse(this::displayAccount, this::displayLogin);
接口
接口有 private 方法:
public?interface?MyInterface?{????private?static?void?myPrivateMethod(){????????System.out.println("Yay, I am private!");????}}
其他語言功能
還有其他一些改進(jìn)喂江,例如改進(jìn)的try-with-resources語句或diamond operator extensions.。
JShell
最后旁振,Java提供了一個(gè)Shell获询,您可以在其中試用簡(jiǎn)單的命令并立即獲得結(jié)果。
% jshell| Welcome to?JShell -- Version 9| For an?introduction type: /help?introjshell> int?x?= 10x?==> 10
HTTP客戶端
Java 9帶來了新版本的初始預(yù)覽版本 HttpClient拐袜。直到那時(shí)吉嚣,Java的內(nèi)置Http支持還只是底層的,您只能依靠Apache HttpClient或OkHttp之類的第三方庫(kù)(它們是很棒的庫(kù)蹬铺,btw3⒍摺)。
使用Java 9丛塌,Java獲得了自己的現(xiàn)代客戶端较解,盡管該客戶端處于預(yù)覽模式畜疾,這意味著它可能會(huì)在更高的Java版本中進(jìn)行更改赴邻。
拼圖項(xiàng)目:Java模塊和多版本jar文件Java 9獲得了 Jigsaw Module System,它在某種程度上類似于舊的 OSGI規(guī)范啡捶。深入了解拼圖姥敛,不在本指南的范圍內(nèi),但是請(qǐng)查看前面的鏈接以了解更多信息瞎暑。
多版本.jar文件使一個(gè).jar文件成為可能彤敛,該文件包含針對(duì)不同JVM版本的不同類。因此了赌,例如墨榄,在Java 8與Java 10上運(yùn)行時(shí),您的程序可以表現(xiàn)不同/具有不同的類勿她。
Java 10
Java 10進(jìn)行了一些更改袄秩,例如垃圾收集等。但是逢并,作為開發(fā)人員之剧,您唯一可能真正看到的更改就是引入了var 關(guān)鍵字,也稱為局部變量類型推斷砍聊。
局部變量類型推斷:var-keyword
// Pre-Java 10String?myName = "Marco";// With Java 10var?myName = "Marco"
感覺是Java語言背稼,不是嗎?但是玻蝌,它仍然是強(qiáng)類型的蟹肘,并且僅適用于方法內(nèi)部的變量 词疼。
Java 11
從開發(fā)人員的角度來看,Java 11的發(fā)行版也較小帘腹。
字符串和文件字符串和文件有幾個(gè)新方法(此處未列出所有方法):
"Marco".isBlank();"Mar\nco".lines();"Marco ".strip();Path path = Files.writeString(Files.createTempFile("helloworld", ".txt"), "Hi, my name is!");String?s = Files.readString(path);
運(yùn)行源文件
從Java 10開始寒跳,您可以運(yùn)行Java源文件, 而無需先對(duì)其進(jìn)行編譯竹椒。邁向腳本編寫的一步童太。
ubuntu@DESKTOP-168M0IF:~$ java MyScript.java
Lambda參數(shù)的局部變量類型推斷(var)
標(biāo)頭說明了一切:
(var?firstName, var?lastName) -> firstName + lastName
HttpClient
在 HttpClient 從Java 9在其最后,非預(yù)覽版胸完。
Java 12
Java 12有一些 新功能和清理功能书释,但是這里唯一值得一提的是Unicode 11支持和新開關(guān)表達(dá)式的預(yù)覽,您將在下一節(jié)中看到赊窥。
Java 13
您可以在此處找到完整的功能列表 爆惧,但從本質(zhì)上講,您將獲得Unicode 12.1支持锨能,以及兩個(gè)新的或改進(jìn)的預(yù)覽功能(將來可能會(huì)更改):
切換表達(dá)(預(yù)覽)
開關(guān)表達(dá)式現(xiàn)在可以返回一個(gè)值扯再。而且您可以對(duì)表達(dá)式使用lambda樣式的語法,而不會(huì)出現(xiàn)直通/突破問題:
舊的switch語句如下所示:
switch(status) {??case?SUBSCRIBER:????// code block????break;??case?FREE_TRIAL:????// code block????break;??default:????// code block}
而在Java 13中址遇,switch語句如下所示:
boolean?result = switch?(status) {????case?SUBSCRIBER -> true;????case?FREE_TRIAL -> false;????default?-> throw?new?IllegalArgumentException("something is murky!");};
多行字符串(預(yù)覽)
您最終可以在Java中執(zhí)行此操作:
String htmlBeforeJava13 = "<html>\n"?+??????????????" <body>\n"?+??????????????" <p>Hello, world</p>\n"?+??????????????" </body>\n"?+??????????????"</html>\n";String htmlWithJava13 = """??????????????<html>??????????????????<body>??????????????????????<p>Hello, world</p>??????????????????</body>??????????????</html>??????????????""";
Java 14及更高版本
一旦發(fā)布熄阻,將在此處進(jìn)行介紹!
結(jié)論
到目前為止倔约,您應(yīng)該對(duì)以下幾件事有了一個(gè)很好的了解:
如何安裝Java秃殉,要獲取的版本以及從何處獲取(提示:AdoptOpenJDK)浸剩。
什么是Java發(fā)行版钾军,存在哪些發(fā)行版以及有什么區(qū)別。
歡迎關(guān)注! 持續(xù)更新技術(shù)干貨!