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

DK19都出來了~是時候梳理JDK的各個版本的特性「JDK9特性講解」

開發(fā) 前端
JAVA9開始,JDK開始以時間為驅(qū)動進(jìn)行更新,以半年為周期,到時即更新,三年出一個長期支持版,其他都是短暫的版本。

一、JDK版本特性

??JAVA8 及之前,版本都是特性驅(qū)動的版本更新,就是有重大的特性產(chǎn)生,然后進(jìn)行更新。

??JAVA9開始,JDK開始以時間為驅(qū)動進(jìn)行更新,以半年為周期,到時即更新,三年出一個長期支持版,其他都是短暫的版本。

??目前的長期支持版有 JAVA8 JAVA11 和JAVA17,這些版本大家注意在將來的工作中使用的概率更高,也就是說我們將來研發(fā),使用JAVA11 ,然后使用JAVA17 是必然的,只是一個時間的問題。

??新的長期支持版每三年發(fā)布一次,根據(jù)后續(xù)的發(fā)布計劃,下一個長期支持的版本JAVA17于2021年發(fā)布。

環(huán)境準(zhǔn)備:

下載JDK,可以通過https://www.injdk.cn/ 去下載各種不同版本的JDK, 因?yàn)镴DK是向下兼容的,所以我們使用一個較新的JDK,就可以去測試和學(xué)習(xí)從9-最新所有版本的新特征了,我們這里以安裝openjdk19為例,下載安裝JDK19的壓縮包。

下載后可以解壓到我們磁盤的任意位置,我這里的位置是 D:\software\openjdk-19.0.1_windows-x64_bin\jdk-19.0.1。

在IDEA中創(chuàng)建項目。可以選擇對應(yīng)的JDK。

當(dāng)然,也可以在項目創(chuàng)建完畢之后,更換JDK為19。

二、JDK9特性講解

1. JDK9特性概述

經(jīng)過4次推遲,歷經(jīng)曲折的Java9最終在2017年9月21日發(fā)布。因?yàn)槔锩婕尤氲哪K化系統(tǒng),在最初設(shè)想的時候并沒有想過那么復(fù)雜,花費(fèi)的時間超出預(yù)估時間。距離java8大約三年時間。 ??Java 9提供了超過150項新功能特性,包括備受期待的模塊化系統(tǒng)、可交互的REPL工具: jshell, JDK編譯工具,語法層面的改變:Java公共API和私有代碼,以及安全增強(qiáng)、擴(kuò)展提升、性能管理改善等。可以說Java 9是一個龐大的系統(tǒng)工程,完全做了一個整體改變。 ?

但是這個巨大改變的功勞,都給了java11了,目前oracle對8,11都長期支持,9,10不支持了,只能從歷史版本(??http://jdk.java.net/)中下載,Java?? 11 將會獲得 Oracle 提供的長期支持服務(wù),直至2026年9月。

從Java9這個版本開始,Java 的計劃發(fā)布周期是6個月,下一個Java的主版本將于2018年3月發(fā)布,命名為Java18.3(java10), 緊接著再過六個月將發(fā)布Java18.9(java11). ??這意味著Java的更新從傳統(tǒng)的以特性驅(qū)動的發(fā)布周期,轉(zhuǎn)變?yōu)橐詴r間驅(qū)動的(6個月為周期)發(fā)布模式**(更快的時間周期,oracle的理念就是小步快跑,快速迭代,像IBM(DB2數(shù)據(jù)庫,保守型內(nèi)部測試才投入市場)),并逐步的將Oracle JDK原商業(yè)特性進(jìn)行開源。針對企業(yè)客戶的需求,Oracle將以三年為周期發(fā)布長期支持版本(long term support)。

2. JDK9的改變

JDK9的具體變化在下面的思維導(dǎo)圖中呈現(xiàn):

官方提供的新特性的列表:

https://docs.oracle.com/javase/9/whatsnew/toc.htm#JSNEW-GUID-C23AFD78-C777-460B-8ACE-58BE5EA681F6。

openJDK 可參考源碼。

http://openjdk.java.net/projects/jdk9/。

在線 OracleJDK Documentation 在線文檔。

https://docs.oracle.com/javase/9/。

3. JDK和JRE目錄變化

??然后我們來看看JDK和JRE在JDK8和JDK9的差異。

目錄作用介紹:

bin 包含命令行開發(fā)和調(diào)試工具 如javac jar javadoc。

include 包含編譯本地代碼時使用的c/c++頭部文件。

lib 包含JDK工具的幾個jar和其他類型的文件,他有一個tools.jar文件,其中含javac編譯器的java類。

jre/bin目錄 包含基本指令,如java指令,在windows平臺上,它包含系統(tǒng)的運(yùn)行時動態(tài)鏈接。

jre/lib包含用戶可編輯的配置文件,如properties和.policy文件,包含幾個jar文件,rt.jar文件包含運(yùn)行時的java類和資源文件。

目錄介紹:

  • bin 包含所有指令,在windows平臺上,他繼續(xù)包含系統(tǒng)的運(yùn)行時動態(tài)鏈接。
  • conf目錄 包含用戶可編輯的配置文件,例如之前位于jre/lib目錄中的.properties和policy。
  • includes 包含在以前編譯本地代碼時使用c/c++頭文件,他只存在于JDK中。
  • jmods 包含JMOD格式的平臺模塊,創(chuàng)建自定義運(yùn)行時映像需要他,它只存在于jdk中。
  • legal 法律聲明。
  • lib 包含非windows平臺上的動態(tài)鏈接本地庫,其子目錄和文件不應(yīng)由開發(fā)人員直接編譯或使用。
  • 從9開始以后的JDK目錄結(jié)構(gòu)都是如此。

4. 語法層次改變

4.1 鉆石操作符號語法升級

鉆石操作符,就是我們泛型使用的符號<>。

JAVA8 中,匿名內(nèi)部類不能使用鉆石操作符,如下代碼在JAVA8 中是報錯的,匿名內(nèi)部類這里不支持泛型推斷,重寫的方法不明確泛型。

這里匿名內(nèi)部類中的<>號里必須要和前面的聲明保持一致,不能空著不寫,這樣重寫的方法就根據(jù)匿名內(nèi)部類的泛型。

但是這種寫法在JAVA9 中就允許了。

而且在JAVA9中,匿名內(nèi)部類的語法不僅僅可以用于接口和抽象類,普通類也可以通過匿名內(nèi)部類寫法,在某個實(shí)例上完成對某個方法的重寫。

public class Demo1 {
public static void main(String[] args){
/*
* 匿名內(nèi)部類僅僅在接口和抽象類上使用,作為一種快速的實(shí)現(xiàn)方式
* JAVA9中,普通類也可以借助這種語法形式實(shí)現(xiàn)對方法的快速臨時的重寫
* */
Person<String> person=new Person<>(){
@Override
public void eat(String s){
super.eat(s);
}
};
person.eat("油條");

}
}
class Person<T>{
public void eat(T t){
System.out.println("Person eat");
}
}

4.2 try結(jié)構(gòu)語法升級

普通的try catch finally語句 要釋放的資源可以放到finally語句塊中。

public class Demo02 {
public static void main(String[] args) {
InputStreamReader reader =null;
try{
reader =new InputStreamReader(System.in);
int read = reader.read();
}catch (Exception e){
throw new RuntimeException(e);
}finally {
// 這里可以釋放資源
if(null != reader){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

JAVA 8中已經(jīng)對try語法進(jìn)行了升級,可以將要釋放的資源放到try后面的小括號中,這樣就不用通過finally語句塊釋放資源了,但是要求執(zhí)行后必須關(guān)閉的資源一定要放在try子句中進(jìn)行初始化,否則編譯不通過. 下面的案例中,reader必須放在try后面的小括號中進(jìn)行初始化。

    public static void main(String[] args){
try( InputStreamReader reader=new InputStreamReader(System.in) ){
int read = reader.read();
}catch (Exception e){
throw new RuntimeException(e);
}
}

JAVA 9 資源的關(guān)閉操作,我們可以在try子句中使用已經(jīng)初始化的資源但是此時的資源必須 是final修飾的,final可以省略不寫。

    // JAVA9 try語法升級
public void testb() throws FileNotFoundException {
// JAVA9 try catch finally語句塊
InputStreamReader isr =new InputStreamReader(new FileInputStream("d:/UserMapper.xml"));
OutputStreamWriter isw =new OutputStreamWriter(new FileOutputStream("d:/UserMapper1.xml"));
try( isr; isw){
isr.read();
}catch (Exception e){
e.printStackTrace();
}
}

4.3 下劃線命名標(biāo)識符的使用限制

標(biāo)識符命名組成:字母,數(shù)字,下劃線,美元符。

JAVA8 中,可以使用一個 _ 作為標(biāo)識符的命名。

JAVA9 中,就不可以使用一個_ 作為標(biāo)識符的命名了,不通過編譯,但是標(biāo)識符中仍然可以使用_,必須配合其他內(nèi)容。

小細(xì)節(jié):注意一下即可,一般也沒人直接單獨(dú)用一個_ 作為標(biāo)識符的命名。

5. API層次的改變

5.1 接口中的私有方法

??接口中的設(shè)計使用在JDK789中都有相關(guān)的變化的。

JAVA7 中,接口只能有抽象方法。

JAVA8 中,接口中static(靜態(tài)不可重寫)和default(可以重寫)修飾的方法可以擁有方法體。

JAVA9 中,接口中可以使用private修飾方法,并擁有方法體,但是接口中的成員變量仍然不能用private修飾。

感覺: 接口中的代碼越來越靠近抽象類,但是仍然是支持多繼承的。

代碼案例

public class Demo4 {
// 接口,是一種規(guī)范和要求
// 實(shí)現(xiàn)多繼承
}

// java7 接口中的方法必須都是抽象的
interface Inter1 {
void methoda();
}

// java8接口可以定義static/default修飾的非抽象方法
interface Inter2 {
void methoda();

static void methodB() {

}

default void methodC() {

}
}

// java9 允許定義私有的非抽象方法
interface Inter3 {
void methoda();

static void methodB() {

}

default void methodC() {
methodD();
}

private void methodD() {

}
}

5.2 String底層存儲結(jié)構(gòu)變化

??JAVA8 中的String源碼,String類內(nèi)部維護(hù)的是一個final修飾的私有char數(shù)組,說明String的底層是通過char數(shù)組存儲字符串的。

??JAVA9 中String的源碼,String類內(nèi)部維護(hù)的是一個final修飾的私有byte數(shù)組,說明String的底層是通過byte數(shù)組存儲字符串的.

這么調(diào)整的原因:

大多數(shù)String對象只包含latin-1字符。 這樣的字符只需要一個字節(jié)的存儲空間,因此這樣的String對象的內(nèi)部字符數(shù)組中有一半的空間沒有使用 , 我們建議將String類的內(nèi)部表示形式從UTF-16字符數(shù)組更改為一個字節(jié)數(shù)組加上一個結(jié)束編碼標(biāo)志字段。

5.3 Stream新增4個API

??JAVA9 中,Stream接口添加了4個新方法,takeWhile,dropWhile,ofNullable,還有一個iterate 方法的新重載方法,可以通過一個Predicate來指定什么時候結(jié)束迭代。

/**
* 測試Stream新增takeWhile方法
* takeWhile 從流中的頭開始取元素,直到不滿足條件為止
*/
public static void testTakeWhile(){
List<Integer> list = Arrays.asList(1, 89, 63, 45, 72, 65, 41, 65, 82, 35, 95, 100);
// 從頭開始取所有奇數(shù),直到遇見一個偶數(shù)為止
list.stream().takeWhile(e-> e%2==1).forEach(System.out::println);

}

/**
* 測試Stream新增dropWhile方法
* dropWhile 從頭開始刪除滿足條件的數(shù)據(jù),直到遇見第一個不滿足的位置,并保留剩余元素
*/
public static void testDropWhile(){
List<Integer> list = Arrays.asList(2, 86, 63, 45, 72, 65, 41, 65, 82, 35, 95, 100);
// 刪除流開頭所有的偶數(shù),直到遇見奇數(shù)為止
list.stream().dropWhile(e-> e%2==0 ).forEach(System.out::println);

}

/**
* 測試Stream新增ofNullable方法
* ofNullable 允許創(chuàng)建Stream流時,只放入一個null
*/
public static void testOfNullable(){
// of方法獲取流 ,允許元素中有多個null值
Stream<Integer> stream1 = Stream.of(10, 20, 30, null);
// 如果元素中只有一個null,是不允許的
Stream<Integer> stream2 = Stream.of(null);
// JAVA9中,如果元素為null,返回的是一個空Stream,如果不為null,返回一個只有一個元素的Stream
Stream<Integer> stream3 = Stream.ofNullable(null);
}

/**
* 測試Stream新增iterate方法
* iterate指定種子數(shù),指定條件和迭代方式來獲取流
*/
public static void testNewIterate(){
//JAVA8通過 generate方法獲取一個Stream
Stream.generate(Math::random).limit(10).forEach(System.out::println);
//JAVA8 通過iterate獲取一個Stream
Stream.iterate(0,t-> t+2).limit(10).forEach(System.out::println);
//JAVA9通過重載iterate獲取Stream
Stream.iterate(0,t -> t<10,t-> t+1).forEach(System.out::println);
}

??除了Stream本身的擴(kuò)展,Optional和Stream之間的結(jié)合也得到了改進(jìn),現(xiàn)在可以通過Optional的新方法將一個Optional對象轉(zhuǎn)換為一個Stream對象(可能是空的)。

    /**
* Optional類新增Stream方法,可以將一個Optional轉(zhuǎn)換為Stream
*/
public static void testOptionalStream(){
List<Integer> list =new ArrayList<>();
Collections.addAll(list,10,5,45,95,36,85,47);
Optional<List<Integer>> optional=Optional.ofNullable(list);

// 通過optional的Stream方法獲取一個Stream
Stream<List<Integer>> stream = optional.stream();
// 以為內(nèi)部的每個元素也是一個List,通過flatMap方法,將內(nèi)部的List轉(zhuǎn)換為Stream后再放入一個大Stream
stream.flatMap(x->x.stream()).forEach(System.out::println);

}

5.4 InputStream新增transferTo方法

??InputStream新增transferTo方法,可以用來將數(shù)據(jù)直接傳輸?shù)絆utpuStream,這是在處理原始數(shù)據(jù)時非常常見的一種方法。

        InputStream inputStream =new FileInputStream("d:/aaa.txt");
OutputStream outputStream=new FileOutputStream("d:/bbb.txt");
try (inputStream;outputStream){
inputStream.transferTo(outputStream);
} catch (IOException e) {
e.printStackTrace();
}

5.5 只讀集合創(chuàng)建

??JAVA8 要創(chuàng)建一個只讀,不可改變的集合,必須構(gòu)造和分配他,然后添加元素,然后再包裝成一個不可修的集合。

        List<String> list= new ArrayList<>();
list.add("Tom");
list.add("Jerry");
list.add("Mark");
list.add("Jhon");
list = Collections.unmodifiableList(list);
System.out.println(list);

??放入數(shù)據(jù)后,然后要通過unmodifiableList才能讓集合變?yōu)橹蛔x集合,不能表達(dá)為單個的表達(dá)式。

JAVA9 通過集合工廠方法,創(chuàng)建一個只讀集合,只要通過新增的of方法即可完成創(chuàng)建。

    public static void main(String[] args){
List<String> list = List.of("張三", "李四", "王五");
System.out.println(list);
list.set(0,"aaa");
System.out.println(list);
}

上面是List接口的of方法, 同樣的,Set接口和Map接口下也新增了of方法,也是返回一個只讀集合。

6. 其他變化

6.1 模塊化

??談到Java9大家往往第一個想到的就是Jigsaw項目(后改名為Modularity)。眾所周知,Java已經(jīng)發(fā)展超過20年(95年最初發(fā)布),Java和相關(guān)生態(tài)在不斷豐富的同時也越來越暴露出一些問題。

Java運(yùn)行環(huán)境的膨脹和臃腫。每次JVM啟動的時候,至少會有30~ 60MB的內(nèi)存加載,主要原因是JVM需要加載rt.jar,不管其中的類是否被classloader加載,第一步整個jar都會被JVM加載到內(nèi)存當(dāng)中去(而模塊化可以根據(jù)模塊的需要加載程序運(yùn)行需要的class)。

當(dāng)代碼庫越來越大,創(chuàng)建復(fù)雜,盤根錯節(jié)的“意大利面條式代碼”的幾率呈指數(shù)級的增長。不同版本的類庫交叉依賴導(dǎo)致讓人頭疼的問題,這些都阻礙了Java 開發(fā)和運(yùn)行效率的提升。

很難真正地對代碼進(jìn)行封裝,而系統(tǒng)并沒有對不同部分(也就是JAR文件)之間的依賴關(guān)系有個明確的概念。每一個公共類都可以被類路徑之下任何其它的公共類所訪問到,這樣就會導(dǎo)致無意中使用了并不想被公開訪問的API。

??本質(zhì)上講,模塊化,就是在package外面包裹一層->>>說白了項目下有眾多 模塊 進(jìn)行項目管理,管理各個模塊,比如一個電商項目 下面有支付模塊 購物模塊,,,模塊跟模塊之間相互調(diào)用,這樣代碼就更安全,可以指定哪些暴露 哪些隱藏!

??模塊之間的可訪問性是所使用的模塊和使用模塊之間的雙向協(xié)議:模塊明確地使其公共類型可供其他模塊使用,而且使用這些公共類型的模塊明確聲明對第一個模塊的依賴,模塊中所有未導(dǎo)出的軟件包都是模塊的私有的,他們不能在模塊之外使用.之前做不到,現(xiàn)在可以考慮這個事了。

案例演示:

創(chuàng)建一個普通的Java項目;

然后在這個項目下準(zhǔn)備兩個模塊。

然后在JDK19Module1中添加一些類就可以了;

然后我們需要考慮如何在JDK19module2中使用這個類? 或者說是使用模塊1中的類,第一步,在兩個模塊的src下創(chuàng)建各自的module-info.java;

創(chuàng)建完畢的結(jié)構(gòu)為:

在JDK19Module1的module-info.java文件中。設(shè)置哪些包可以向外暴露;

然后在JDK19Module2的module-info.java中引入模塊2;

但是發(fā)現(xiàn)報錯了,原因是,我們要把模塊1添加為模塊2的運(yùn)行環(huán)境,具體操作如下:

project structure > modules > JDK19Module2>dependencies >>+module lib > JDK19Module1> apply >>ok。

這個是時候,我們在模塊2中就可以使用模塊1 中的類了。

6.2 可交互的REPL工具

??像Python和Scala 之類的語言早就有交互式編程環(huán)境REPL (read -evaluate - print -loop)了,以交互式的方式對語句和表達(dá)式進(jìn)行求值。開發(fā)者只需要輸入一些代碼,就可以在編譯前獲得對程序的反饋。而之前的Java 版本要想執(zhí)行代碼,必須創(chuàng)建文件、聲明類、提供測試方法方可實(shí)現(xiàn)。

要想實(shí)現(xiàn)REPL,需要一個命令:JShell命令(linux中是shell命令,java中的shell命令)。

??將環(huán)境變量配置為java9,就可以在控制命令臺使用jshell命令了:如果電腦上安裝了其他版本的JDK,環(huán)境變量也是其他版本,大家可以在dos上通過cd 切換到指定版本的bin目錄下,就可以使用該版本的jshell了。

簡單的輸出語句;

變量定義:

方法定義和調(diào)用;

導(dǎo)包處理;

??其實(shí)jshell中有默認(rèn)的導(dǎo)入一些包(除了java.lang之外,以下包也可以直接用),可以直接使用不用導(dǎo)包,查看有哪些:

常用命令;

上面操作的代碼關(guān)閉窗口后就消失了。如果我們需要持久化相關(guān)的代碼,也可以操作;

退出jshell?;

/exit
責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2009-07-09 16:29:19

JDK版本

2024-01-23 08:23:24

Java虛擬線程

2022-07-28 07:57:27

JDK 19Java

2009-07-09 11:43:22

JDK1.4assert

2024-01-26 08:33:14

JDK17JDK11版本

2009-07-07 12:30:38

JDK1.6

2010-09-25 09:30:28

JDK 7Java 7

2021-05-06 20:03:00

JavaStream代碼

2011-07-29 09:31:32

JDK 7

2024-04-03 08:47:58

React服務(wù)端組件Actions

2018-06-20 15:50:38

JDK9JVMJDK10

2022-04-08 16:42:11

Stringchar[]byte[]

2021-05-05 11:31:15

JDK新特性Lambda表達(dá)式Java8

2010-06-22 11:07:42

JDK 7Java開發(fā)Java

2011-05-20 09:43:23

JDK7

2009-07-09 10:28:19

線程池JDK5

2011-05-20 09:35:22

JDK7

2024-04-28 09:01:06

React 19更新前端

2019-03-04 09:39:41

Java開發(fā)代碼

2009-11-23 20:16:17

PHP接口特性
點(diǎn)贊
收藏

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