自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用了23年的Java不再免費!

開發(fā) 后端
就在 Java 早已在移動 App、服務(wù)器應(yīng)用、Web 開發(fā)、J2EE 企業(yè)級應(yīng)用和嵌入式等領(lǐng)域根深蒂固時,Oracle 于近日最新發(fā)布的一紙 Java 用戶使用協(xié)議轟動了整個業(yè)界,因為 Java 將收費了!

上個月,Java 開發(fā)工具包(JDK)11剛剛到來,JDK 12 就在緊密敲鑼籌備中,隨著消息接連不斷地爆出,不少使用 Java 的開發(fā)者開始有種一年一萬個更新版本的錯覺,而當面對厚厚的一堆堆 Java 8/9/10/11 的入門書籍和教程時,就問你怕不怕?不僅如此,就在 Java 早已在移動 App、服務(wù)器應(yīng)用、Web 開發(fā)、J2EE 企業(yè)級應(yīng)用和嵌入式等領(lǐng)域根深蒂固時,Oracle 于近日***發(fā)布的一紙 Java 用戶使用協(xié)議轟動了整個業(yè)界,因為 Java 將收費了!

1.JDK 11 不容錯過的那些新特性

JDK 11 作為 Oracle 以六個月為更新周期之后公開發(fā)布的***個長期支持版本,其中還是有許多實用的功能特性。

局部變量推斷

Java 10 引入了新的關(guān)鍵字 var,可以在定義局部變量時代替類型信息(局部指的是在方法體內(nèi)部的變量定義)。

在 Java 10 之前,局部變量必須這樣定義:

  1. String text = "Hello Java 9"

而現(xiàn)在可以用 var 代替 String。編譯器會根據(jù)變量的賦值推斷出正確的類型。因此,text 的類型是 String:

  1. var text = "Hello Java 10"

使用 var 定義的變量依然是靜態(tài)類型。這種變量不能重新用不兼容的類型賦值。比如,下面的代碼無法通過編譯:

 

  1. var text = "Hello Java 11" 
  2. text = 23; // Incompatible types 

還可以通過同時使用 var 和 final 來禁止變量的重新賦值:

 

  1. final var text = "Banana" 
  2. text = "Joe"; // Cannot assign a value to final variable 'text' 

而且,當編譯器無法推斷出正確類型時也不允許使用 var:

 

  1. // Cannot infer type:  
  2. var a;  
  3. var nothing = null 
  4. var lambda = () -> System.out.println("Pity!");  
  5. var method = this::someMethod; 

局部變量類型的推斷在泛型中非常有用。下面的例子中,current 有個非常復(fù)雜的類型 Map>,而這個類型可以簡化成一個 var 關(guān)鍵字,節(jié)省了很多敲代碼的時間:

 

  1. var myList = new ArrayList>>();  
  2. for (var current : myList) {  
  3. // current is infered to type: Map>  
  4. System.out.println(current);  
  5.  由于 Java 11 的 var 關(guān)鍵字也可以在 lambda 的參數(shù)上使用,因此可以給參數(shù)加注解:  
  6. Predicate predicate = (@Nullable var a) -> true

小提示:Intellij IDEA 中可以按住 CMD/CTRL 鍵并將鼠標懸停在變量上來查看推斷出的類型(鍵盤快捷鍵為Ctrl+J)。

HTTP 客戶端

Java 9 引入了新的 HttpClient API 來處理 HTTP 請求。在 Java 11 中,這個 API 已穩(wěn)定,可以通過 java.net 包使用。我們來看看這個 API 能干什么。

新的 HttpClient 支持同步和異步方式。同步請求會阻塞當前線程直到響應(yīng)返回。BodyHandlers 定義了期待的響應(yīng)體的類型(如字符串、字節(jié)數(shù)組或文件):

 

  1. var request = HttpRequest.newBuilder()  
  2. .uri(URI.create("https://winterbe.com"))  
  3. .GET()  
  4. .build();  
  5. var client = HttpClient.newHttpClient();  
  6. HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());  
  7. System.out.println(response.body()); 

同樣的請求也可以異步進行。調(diào)用 sendAsync 不會阻塞當前線程,它會返回一個 CompletableFuture 用來構(gòu)建異步操作管線。

 

  1. var request = HttpRequest.newBuilder()  
  2. .uri(URI.create("https://winterbe.com"))  
  3. .build();  
  4. var client = HttpClient.newHttpClient();  
  5. client.sendAsync(request, HttpResponse.BodyHandlers.ofString())  
  6. .thenApply(HttpResponse::body)  
  7. .thenAccept(System.out::println); 

小提示:可以省略 .GET() 調(diào)用,因為它是默認的。

下面這個例子用 POST 方式將數(shù)據(jù)發(fā)送到給定的 URL。與 BodyHandlers 類似,這里使用 BodyPublishers 來定義請求體中要發(fā)送的數(shù)據(jù)類型,如字符串、字節(jié)數(shù)組、文件或輸入流:

 

  1. var request = HttpRequest.newBuilder()  
  2. .uri(URI.create("https://postman-echo.com/post"))  
  3. .header("Content-Type""text/plain" 
  4. .POST(HttpRequest.BodyPublishers.ofString("Hi there!"))  
  5. .build();  
  6. var client = HttpClient.newHttpClient();  
  7. var response = client.send(request, HttpResponse.BodyHandlers.ofString());  
  8. System.out.println(response.statusCode()); // 200 

下面的例子演示了通過 BASIC-AUTH 方式進行認證的方法:

 

  1. var request = HttpRequest.newBuilder()  
  2. .uri(URI.create("https://postman-echo.com/basic-auth"))  
  3. .build();  
  4. var client = HttpClient.newBuilder()  
  5. .authenticator(new Authenticator() {  
  6. @Override  
  7. protected PasswordAuthentication getPasswordAuthentication() {  
  8. return new PasswordAuthentication("postman""password".toCharArray());  
  9.  
  10. })  
  11. .build();  
  12. var response = client.send(request, HttpResponse.BodyHandlers.ofString());  
  13. System.out.println(response.statusCode()); // 200 

集合

像 List、Set 和 Map 等集合類都加入了新的方法。List.of 會根據(jù)給定的參數(shù)創(chuàng)建一個新的不可變的 list。List.copyOf 能創(chuàng)建 list 的不可變副本。

 

  1. var list = List.of("A""B""C");  
  2. var copy = List.copyOf(list);  
  3. System.out.println(list == copy); // true 

因為 list 已經(jīng)是不可變的了,因此不需要實際創(chuàng)建 list 實例的副本,因此 list 和 copy 會指向同一個副本。但如果賦值一個可變的列表,copy 就會生成一個新的實例,以保證修改原始列表時不會產(chǎn)生副作用:

 

  1. var list = new ArrayList();  
  2. var copy = List.copyOf(list);  
  3. System.out.println(list == copy); // false 

在創(chuàng)建不可變的 map 時,不需要自行創(chuàng)建 map 的內(nèi)容,只需要傳遞鍵和值即可:

 

  1. var map = Map.of("A", 1, "B", 2);  
  2. System.out.println(map); // {B=2, A=1} 

Java 11 中的不可變集合依然使用與原來的集合 API 同樣的接口。但如果試圖通過添加或刪除元素的方式改變不可變集合,則會發(fā)生 java.lang.UnsupportedOperationException 異常。好在 Intellij IDEA 會在你試圖改變不可變集合時發(fā)出警告。

Java 8 引入了 流的概念,現(xiàn)在它有三個新的方法。Stream.ofNullable 能從單個元素構(gòu)建一個流:

 

  1. Stream.ofNullable(null 
  2. .count() // 0 

dropWhile 和 takeWhile 兩個方法都能接受 predicate 對象,從而可以拋棄流中的一些元素:

 

  1. Stream.of(1, 2, 3, 2, 1)  
  2. .dropWhile(n -> n < 3)  
  3. .collect(Collectors.toList()); // [3, 2, 1]  
  4. Stream.of(1, 2, 3, 2, 1)  
  5. .takeWhile(n -> n < 3)  
  6. .collect(Collectors.toList()); // [1, 2] 

Optional

Optional 也增加了幾個新方法,比如現(xiàn)在可以很容易將 optional 轉(zhuǎn)換成流,或者給空的 optional 提供另一個 optional 作為出錯時的備選方案:

 

  1. Optional.of("foo").orElseThrow(); // foo  
  2. Optional.of("foo").stream().count(); // 1  
  3. Optional.ofNullable(null 
  4. .or(() -> Optional.of("fallback"))  
  5. .get(); // fallback 

字符串

最基礎(chǔ)的類之一 String 也加了幾個輔助方法用來去除空白、檢查空白,以及以流的方式輸出字符串:

 

  1. " ".isBlank(); // true  
  2. " Foo Bar ".strip(); // "Foo Bar"  
  3. " Foo Bar ".stripTrailing(); // " Foo Bar"  
  4. " Foo Bar ".stripLeading(); // "Foo Bar "  
  5. "Java".repeat(3); // "JavaJavaJava"  
  6. "ABC".lines().count(); // 3 

其他 JVM 特性

在我看來,上述這些是 Java 11 與 8 相比時最有意思的語言 API 特性,不過新的特性還有許多,比如下面這些:

  • 用于響應(yīng)式編程的流式 API
  • Java 模塊系統(tǒng)
  • 應(yīng)用程序類數(shù)據(jù)共享
  • 動態(tài)類-文件常量
  • Java REPL(JShell)
  • 飛行記錄器
  • Unicode 10
  • G1:完全并行的垃圾回收器
  • ZGC:可擴展的低延遲垃圾回收器
  • Epsilon:No-Op垃圾回收器
  • 不推薦使用的Nashorn JavaScript引擎
  • ……

2.學(xué)不動的 Java,還要收費了?

對于 Java 新版本,不少開發(fā)者望塵莫及,紛紛表示不要再更新了,我的項目還停留在 Java 8 呢。話雖如此,事實上 Oracle 曾在今年四月就宣布,自 2019 年 1 月起,Java SE 8 公開更新將不向沒有商用許可證的業(yè)務(wù)、商用或生產(chǎn)用途提供。即未來開發(fā)者還想使用 JDK 8,Oracle 將不會提供免費的技術(shù)支持,需要另外收費。所以總體而言還是建議開發(fā)者應(yīng)該轉(zhuǎn)換到***版的 Java 11。

使用了23年的Java不再免費!

但就在這時,據(jù)國外網(wǎng)友@Stephen Colebourne 發(fā)布的一篇名為《Oracle's Java 11 trap - Use OpenJDK instead!》博文,我們才注意到,在 Java 11 中,Oracle 悄然更新了用戶使用協(xié)議(https://www.oracle.com/technetwork/java/javase/terms/license/javase-license.html):

使用了23年的Java不再免費!

簡而言之:

新版 Oracle JDK 不可以用在數(shù)據(jù)處理、商業(yè)、產(chǎn)品、或者內(nèi)部商業(yè)用途(需要購買 License),僅可免費用于開發(fā)、測試、原型、演示。

使用了23年的Java不再免費!

正是這一修改意味著免費使用 23 年的 Java 即將走上收費的路子。倘若開發(fā)者還是如往常那般下載 Oracle JDK,并將其投入商業(yè)項目中使用,后續(xù)可能會帶來不小的商業(yè)糾紛。

3.Oracle JDK 收費了,企業(yè)和開發(fā)者怎么辦?

提及 Java 的商業(yè)糾紛,我們不禁想起此前轟動一時且長達八年的 Oracle 與 Google 關(guān)于 Java 的侵權(quán)案:

  • 1995 年,Sun 公司發(fā)布了 Java;
  • 這其中需要介紹到 2006 年,Sun 公司開源了其 Java 項目——OpenJDK,但是并未開源此前的 Java 項目 SunJDK(現(xiàn)在是 OracleJDK);
  • 2009 年,Oracle 以 74 億美元收購 Sun 從而獲得了 Java 的版權(quán),而其中也包含了 Sun 研發(fā)的 Java 商業(yè)項目版權(quán);
  • 2010 年 8 月,Oracle 認為 Google Android 系統(tǒng)抄襲了 37 個 Java API 代碼段,而這些代碼屬于 Oracle 商業(yè)私有 JDK(OracleJDK)的一部分,于是將 Google 訴訟至法庭,要求賠償 26 億美元;

經(jīng)過 8 年的調(diào)解及上訴,這一案最終于今年 3 月,美國聯(lián)邦巡回法院判 Google 向 Oracle 賠償 88 億美元而告一段落。之所以沒說案件告終,是因為 Google 不服判決,還在向***法院上訴中。

而就在 Google 邊應(yīng)對訴訟時,或許就在周密思量針對自己的 Android 系統(tǒng)甚至是整個公司研發(fā)的下一步:如何擺脫 Oracle?

于是,在 2015 年年底,我們就親眼見證了 Google 宣布將 Java 應(yīng)用程序接口(APIs)從 Oracle JavaAPI 替換成開源的 OpenJDK。甚至在兩年后的 Google I/O 大會上,震撼宣布 Kotlin 成為 Android 開發(fā)的一級編程語言,讓其與 Java 齊駕并驅(qū),反觀,也是與之相抗衡。

再針對這一次的 Oracle 修改了 JDK 11 的用戶協(xié)議來看,從 Oracle 的角度其實不難理解他的這一行為,畢竟作為純軟件先驅(qū)的 Oracle 也是個商業(yè)公司,他需要提供一個軟件的商業(yè)版本來提高增值服務(wù)。但是對于使用 Oracle JDK 的開發(fā)者或企業(yè)而言,情況就變得有所不同了,為了避免上述 Google 的同等遭遇,我們除了付費是否還有其他選擇?

對此,不少開發(fā)者紛紛熱議:

  • Java 程序員是時候向 C# 轉(zhuǎn)移了;
  • 換 .NET 也行;

這個僅針對 JDK 11,不升級不使用 Java 11 不就行了。

在訪問了幾位知名的 Java 開發(fā)者之后,他們給出的答案幾乎都是,「使用 Kotlin」。甚至就連微博研發(fā)副總經(jīng)理@TimYang 也表示,這一行為直接導(dǎo)致 Kotlin 才是***贏家,IDEA 環(huán)境將 Java 代碼粘貼到 Kotlin 文件,自動轉(zhuǎn)換。

使用了23年的Java不再免費!

不過相較于 23 歲的 Java,不少開發(fā)者還是對年僅 7 歲的 Kotlin 的未來感到迷茫,所以在面對 JDK 8 即將停止免費更新支持、JDK 11 無法商用的情況下,請記得 Oracle 還有一個名為 OpenJDK 的開源項目。

注:Java 9、10 并不是長期支持(LTS)版本,所以上述文章中并未提及。

要說 Oracle JDK 和 Open JDK 之前的差距很明顯,那么在 JDK 11 中,Oracle 很人性化地將兩者的不同盡可能地縮小了,甚至可以忽略微乎其微的差距。

或者除了 Open JDK 外,我們此前也發(fā)文為大家推薦了一些實用的JDK,譬如 AdoptOpenJDK builds、Red Hat OpenJDK builds、Azul Zulu 等等。***,對于 Oracle 修改 JDK 11 的使用協(xié)議,你有著什么樣的看法?歡迎下方留言,分享你的想法。

責(zé)任編輯:未麗燕 來源: 簡書
相關(guān)推薦

2019-12-12 11:53:13

安全工具網(wǎng)絡(luò)安全網(wǎng)絡(luò)攻擊

2018-05-31 16:42:04

2011-03-22 13:16:49

jQueryjQuery插件

2015-08-31 10:01:24

Windows 10更新

2009-03-24 09:12:06

Windows 7使用技巧微軟

2021-12-12 09:30:19

Bitdefender殺毒軟件安全行業(yè)

2020-12-09 14:37:43

Travis CI開源免費

2023-09-07 10:31:27

2023-10-31 16:34:19

2022-11-04 11:34:15

文件pathlibfileinput

2024-05-08 14:12:40

Redis軟件開源

2018-08-02 11:31:15

小說

2023-01-05 11:34:46

PandasMerge方法

2024-04-02 11:13:10

2014-09-12 12:49:38

容聯(lián)云通信視頻會議

2022-10-08 06:49:32

LinuxWindows操作系統(tǒng)

2019-09-09 16:10:32

ETL數(shù)據(jù)科學(xué)數(shù)據(jù)

2023-12-27 08:33:47

垃圾回收機制

2015-09-18 16:17:03

刪除內(nèi)核Ubuntu

2012-04-05 13:37:10

JavaString
點贊
收藏

51CTO技術(shù)棧公眾號