Java程序員必備基礎(chǔ):JDK 5-15都有哪些經(jīng)典新特性
前言
JDK 15發(fā)布啦~ 我們一起回顧JDK 5-15 的新特性吧,大家一起學(xué)習(xí)哈~
本文已經(jīng)收錄到github
?https://github.com/whx123/JavaHome
?
「公眾號:撿田螺的小男孩」
Java 5 新特性

1. 泛型
泛型本質(zhì)是參數(shù)化類型,解決不確定具體對象類型的問題。
?List?strList=new?ArrayList();
2. 增強循環(huán)(for-each)
for-each循環(huán)簡化了集合的遍歷。
String?[]?str?=?{"關(guān)注","公眾號","撿田螺的小男孩"};
for?(String?temp:str)?{
?????System.out.println(temp);
}
3. 自動封箱拆箱
自動裝箱: 就是將基本數(shù)據(jù)類型自動轉(zhuǎn)換成對應(yīng)的包裝類。 自動拆箱:就是將包裝類自動轉(zhuǎn)換成對應(yīng)的基本數(shù)據(jù)類型。
包裝類型有:Integer,Double,Float,Long,Short,Character和Boolean
Integer?i?=666;??//自動裝箱
int?a=?i;?????//自動拆箱
4. 枚舉
關(guān)鍵字enum可以將一組具名的值的有限集合創(chuàng)建為一種新的類型,而這些具名的值可以作為常規(guī)的程序組件使用,這就是枚舉類型。
enum?SeasonEnum?{
????SPRING,SUMMER,FALL,WINTER;
}
5. 可變參數(shù)
我們在定義方法參數(shù)的時候不確定定義多少個,就可以定義為「可變參數(shù)」,它本質(zhì)上是一個「數(shù)組」。
public?static?void?main(String[]?args)?throws?Exception?{
????String?[]?str?=?{"關(guān)注","公眾號","撿田螺的小男孩"};
????testVarargs(str);
????String?str1?=?"關(guān)注公眾號,撿田螺的小男孩";
????testVarargs(str1);
}
//可變參數(shù)String...?args
private?static?void?testVarargs(String...?args)?{
????for?(String?arg?:?args)?{
????????System.out.println(arg);
????}
}
6. 注解
可以把注解理解為代碼里的特殊標(biāo)記,這些標(biāo)記可以在編譯,類加載,運行時被讀取,并執(zhí)行相應(yīng)的處理。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public?@interface?Override?{
}
7.靜態(tài)導(dǎo)入
通過import static類,就可以使用類里的靜態(tài)變量或方法??匆幌吕庸
import?static?java.lang.System.out;?//靜態(tài)導(dǎo)入System類的靜態(tài)變量out
public?class?Test?{
????public?static?void?main(String[]?args)?throws?Exception?{
????????String?str1?=?"關(guān)注公眾號,撿田螺的小男孩";
????????System.out.println(str1);?//常規(guī)寫法
????????out.println(str1);??//靜態(tài)導(dǎo)入,可以直接使用out輸出
????}
}
8. 線程并發(fā)庫(JUC)
JDK5 豐富了線程處理功能,java.util.concurrent包提供了以下的類、接口:
??
線程池:ExecutorService接口 線程護斥:Lock 類 線程通信:Condition接口 同步隊列:ArrayBlockingQueue類 同步集合:ConcurrentHashMap類
Java 6 新特性

1.Desktop類和SystemTray類
JDK 6在java.awt包下,新增了兩個類:Desktop類和SystemTray類
??
「Desktop類」: 用來打開系統(tǒng)默認瀏覽器瀏覽指定的URL,打開系統(tǒng)默認郵件客戶端發(fā)郵件等 「SystemTray類」:用來在系統(tǒng)托盤區(qū)創(chuàng)建一個托盤程序,如果在微軟的Windows上,它被稱為“任務(wù)欄”狀態(tài)區(qū)域。
//獲取Desktop實例
Desktop?desktop?=?Desktop.getDesktop();
desktop.browse(URI.create("https://www.baidu.com"));
2. 使用JAXB2來實現(xiàn)對象與XML之間的映射
JAXB,即Java Architecture for XML Binding,可以實現(xiàn)對象與XML之間的映射,常用注解如下:
??
@XmlRootElement:注解在類上面,對應(yīng)xml的跟元素,使用name屬性定義根節(jié)點的名稱。 @XmlElement:指定一個字段或get/set方法映射到xml的節(jié)點,使用name屬性定義這個根節(jié)點的名稱。 @XmlAttribute:將JavaBean對象的屬性映射為xml的屬性,使用name屬性為生成的xml屬性指定別名。 @XmlAccessorType:定義映射這個類中的何種類型都需要映射到xml。 @XmlSchema: 將包映射到XML名稱空間
「看個例子吧~」
public?class?JAXB2XmlTest?{
????public?static?void?main(String[]?args)?throws?JAXBException,?IOException?{
????????
????????List?list?=?new?ArrayList<>();
????????list.add(new?Singer("jay",?8));
????????list.add(new?Singer("eason",?10));
????????SingerList?singerList?=?new?SingerList();
????????singerList.setSingers(list);
????????String?str?=?JAXB2XmlTest.beanToXml(singerList,?SingerList.class);
????????String?path?=?"C:\\jay.txt";
????????BufferedWriter?bfw?=?new?BufferedWriter(new?FileWriter(new?File(path)));
????????bfw.write(str);
????????bfw.close();
????}
????private?static?String?beanToXml(Object?obj,?Class>?load)?throws?JAXBException?{
????????JAXBContext?context?=?JAXBContext.newInstance(load);
????????Marshaller?marshaller?=?context.createMarshaller();
????????marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,?true);
????????marshaller.setProperty(Marshaller.JAXB_ENCODING,?"GBK");
????????StringWriter?writer?=?new?StringWriter();
????????marshaller.marshal(obj,writer);
????????return?writer.toString();
????}
}
public?class?Singer?{
????private?String?name;
????private?int?age;
????public?Singer(String?name,?int?age)?{
????????this.name?=?name;
????????this.age?=?age;
????}
????@XmlAttribute(name="name")
????public?String?getName()?{
????????return?name;
????}
????public?void?setName(String?name)?{
????????this.name?=?name;
????}
????@XmlAttribute(name="age")
????public?int?getAge()?{
????????return?age;
????}
????public?void?setAge(int?age)?{
????????this.age?=?age;
????}
}
@XmlRootElement(name="list")
public?class?SingerList?{
????private?List?singers;
????
????@XmlElement(name="singer")
????public?List?getSingers()?{
????????return?singers;
????}
????public?void?setSingers(List?singers)?{
????????this.singers?=?singers;
????}
}
「運行效果:」
"1.0"?encoding="GBK"?standalone="yes"?>
????"8"?name="jay"/>
????"10"?name="eason"/>
3.輕量級 Http Server API
JDK 6中提供了簡單的Http Server API,可以構(gòu)建嵌入式Http服務(wù)器,同時支持Http和Https協(xié)議。HttpServer會調(diào)用HttpHandler實現(xiàn)類的回調(diào)方法來處理客戶端請求,這里用戶只需實現(xiàn)HttpHandler接口就可以了。
/**
?*?根據(jù)Java提供的API實現(xiàn)Http服務(wù)器
?*/
public?class?MyHttpServer?{
????/**
?????*?@param?args
?????*?@throws?IOException
?????*/
????public?static?void?main(String[]?args)?throws?IOException?{
????????//創(chuàng)建HttpServer服務(wù)器
????????HttpServer?httpServer?=?HttpServer.create(new?InetSocketAddress(8080),?10);
????????//將?/jay請求交給MyHandler處理器處理
????????httpServer.createContext("/",?new?MyHandler());
????????httpServer.start();
????}
}
public?class?MyHandler?implements?HttpHandler?{
????public?void?handle(HttpExchange?httpExchange)?throws?IOException?{
????????//請求頭
????????Headers?headers?=?httpExchange.getRequestHeaders();
????????Set>>?entries?=?headers.entrySet();
????????StringBuffer?response?=?new?StringBuffer();
????????for?(Map.Entry>?entry?:?entries){
????????????response.append(entry.toString()?+?"\n");
????????}
????????//設(shè)置響應(yīng)頭屬性及響應(yīng)信息的長度
????????httpExchange.sendResponseHeaders(200,?response.length());
????????//獲得輸出流
????????OutputStream?os?=?httpExchange.getResponseBody();
????????os.write(response.toString().getBytes());
????????os.close();
????}
}
4. 插入式注解處理API
?JDK 6提供了插入式注解處理API,可以讓我們定義的注解在編譯期而不是運行期生效,從而可以在編譯期修改字節(jié)碼。lombok框架就是使用該特性來實現(xiàn)的,Lombok通過注解的方式,在編譯時自動為屬性生成構(gòu)造器、getter/setter、equals、hashcode、toString等方法,大大簡化了代碼的開發(fā)。
?
5. STAX
STAX,是JDK6中一種處理XML文檔的API。
public?class?STAXTest?{
????public?static?void?main(String[]?args)?throws?Exception?{
????????XMLInputFactory?xmlInputFactory?=?XMLInputFactory.newInstance();
????????XMLEventReader?xmlEventReader?=?xmlInputFactory.createXMLEventReader(new?FileInputStream("C:\\jay.xml"));
????????XMLEvent?event?=?null;
????????StringBuffer?stringBuffer?=?new?StringBuffer();
????????while?(xmlEventReader.hasNext())?{
????????????event?=?xmlEventReader.nextEvent();
????????????stringBuffer.append(event.toString());
????????}
????????System.out.println("xml文檔解析結(jié)果:");
????????System.out.println(stringBuffer);
????}
}
「運行結(jié)果:」
xml文檔解析結(jié)果:
"1.0"?encoding='GBK'?standalone='yes'?>
????'jay'?age='8'>
????'eason'?age='10'>
ENDDOCUMENT
6. Common Annotations
?Common annotations原本是Java EE 5.0(JSR 244)規(guī)范的一部分,現(xiàn)在SUN把它的一部分放到了Java SE 6.0中。隨著Annotation元數(shù)據(jù)功能加入到Java SE 5.0里面,很多Java 技術(shù)都會用Annotation部分代替XML文件來配置運行參數(shù)。
?
以下列舉Common Annotations 1.0里面的幾個Annotations:
@Generated:用于標(biāo)注生成的源代碼 @Resource: 用于標(biāo)注所依賴的資源,容器據(jù)此注入外部資源依賴,有基于字段的注入和基于setter方法的注入兩種方式 。 @Resources:同時標(biāo)注多個外部依賴,容器會把所有這些外部依賴注入 @PostConstruct:標(biāo)注當(dāng)容器注入所有依賴之后運行的方法,用來進行依賴注入后的初始化工作,只有一個方法可以標(biāo)注為PostConstruct 。 @PreDestroy:當(dāng)對象實例將要被從容器當(dāng)中刪掉之前,要執(zhí)行的回調(diào)方法要標(biāo)注為PreDestroy
7. Compiler API
javac編譯器可以把.java的源文件編譯為.class文件,JDK 6的新特性Compiler API(JSR 199)也可以動態(tài)編譯Java源文件。
public?class?CompilerApiTest?{
????public?static?void?main(String[]?args)?throws?Exception?{
????????JavaCompiler?javaCompiler?=?ToolProvider.getSystemJavaCompiler();
????????StandardJavaFileManager?standardJavaFileManager?=?javaCompiler.getStandardFileManager(null,null,null);
????????Iterable?extends?JavaFileObject>?javaFileObjects?=?standardJavaFileManager.getJavaFileObjects("C:\\Singer.java");
????????javaCompiler.getTask(null,?standardJavaFileManager,?null,?null,?null,?javaFileObjects).call();
????????standardJavaFileManager.close();
????}
}
運行結(jié)果:會在C目錄生成Singer.class文件
8. 對腳本語言的支持(如: ruby, groovy, javascript)
JDK6增加了對腳本語言的支持(JSR 223),原理是將腳本語言編譯成字節(jié)碼,這樣腳本語言也能享用Java平臺的諸多優(yōu)勢,包括可移植性,安全等。JDK6實現(xiàn)包含了一個基于Mozilla Rhino的 腳本語言引擎,因此可以支持javascript,當(dāng)然JDK也支持ruby等其他語言
public?class?JavaScriptTest?{
????public?static?void?main(String[]?args)?throws?Exception?{
????????ScriptEngineManager?factory?=?new?ScriptEngineManager();
????????ScriptEngine?engine?=?factory.getEngineByName("JavaScript");
????????String?script;
????????try?{
????????????script?=?"print('Hello')";
????????????engine.eval(script);//?執(zhí)行腳本
????????}catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????}
}
//output
Hello
Java 7 新特性

1.switch 支持String字符串類型。
String?singer?=?"jay";
switch?(singer)?{
???????case?"jay"?:
????????????System.out.println("周杰倫");
?????????????break;
???????case?"eason"?:
????????????System.out.println("陳奕迅");
????????????break?;
???????default?:
????????????System.out.println("其他");
????????????break?;
???}
2.try-with-resources,資源自動關(guān)閉
JDK 7 之前:
BufferedReader?br?=?new?BufferedReader(new?FileReader("d:七里香.txt"));
try?{
???return?br.readLine();
}?finally?{
???br.close();
}
JDK 7 之后:
/*
?*?聲明在try括號中的對象稱為資源,在方法執(zhí)行完畢后會被自動關(guān)閉
?*/
try?(BufferedReader?br?=?new?BufferedReader(new?FileReader("d:七里香.txt"))?{
???return?br.readLine();
}
3. 整數(shù)類型如(byte,short,int,long)能夠用二進制來表示
//0b或者0B表示二進制
int?a?=?0b010;
int?b?=?0B010;
4. 數(shù)字常量支持下劃線
int?a?=?11_11;//a的值為1111,下劃線不影響實際值,提升可讀性
5. 泛型實例化類型自動推斷,即”<>”
JDK 7 之前:
Map>?map?=?new?HashMap>();
JDK 7之后:
//不須聲明類型,自動根據(jù)前面<>推斷其類型
Map>?map?=?new?HashMap<>();
6.一個catch中捕獲多個異常類型,用(|)分隔開
JDK 7之前
try{
???//do?something
}?catch?(FirstException?e)?{
?????logger.error(e);
}?catch?(SecondException?e)?{
?????logger.error(ex);
}
JDk 7之后
try{
???//do?something
}?catch?(FirstException?|?SecondException?e)?{
?????logger.error(e);
}
7. 增強的文件系統(tǒng)
Java7 提供了全新的NIO2.0 API,方便文件管理的編碼。如,可以在java.nio.file包下使用Path、Paths、Files、WatchService等常用類型。
Path?path?=?Paths.get("C:\\jay\\七里香.txt");?//創(chuàng)建Path對象
byte[]?bytes=?Files.readAllBytes(path);??//讀取文件
System.out.println(path.getFileName());?//獲取當(dāng)前文件名稱
System.out.println(path.toAbsolutePath());?//?獲取文件絕對路徑
System.out.println(new?String(bytes,?"utf-8"));
8. Fork/join 框架
Java7提供的一個用于并行執(zhí)行任務(wù)的框架,是一個把大任務(wù)分割成若干個小任務(wù),最終匯總每個小任務(wù)結(jié)果后得到大任務(wù)結(jié)果的框架。
Fork/join計算1-1000累加值:
public?class?ForkJoinPoolTest?{
????private?static?final?Integer?DURATION_VALUE?=?100;
????static?class?ForkJoinSubTask?extends?RecursiveTask{
????????//?子任務(wù)開始計算的值
????????private?Integer?startValue;
????????//?子任務(wù)結(jié)束計算的值
????????private?Integer?endValue;
????????private?ForkJoinSubTask(Integer?startValue?,?Integer?endValue)?{
????????????this.startValue?=?startValue;
????????????this.endValue?=?endValue;
????????}
????????@Override
????????protected?Integer?compute()?{
????????????//小于一定值DURATION,才開始計算
????????????if(endValue?-?startValue?????????????????System.out.println("執(zhí)行子任務(wù)計算:開始值?=?"?+?startValue?+?";結(jié)束值?=?"?+?endValue);
????????????????Integer?totalValue?=?0;
????????????????for?(int?index?=?this.startValue;?index?<=?this.endValue;?index++)?{
????????????????????totalValue?+=?index;
????????????????}
????????????????return?totalValue;
????????????}?else?{
????????????????//?將任務(wù)拆分,拆分成兩個任務(wù)
????????????????ForkJoinSubTask?subTask1?=?new?ForkJoinSubTask(startValue,?(startValue?+?endValue)?/?2);
????????????????subTask1.fork();
????????????????ForkJoinSubTask?subTask2?=?new?ForkJoinSubTask((startValue?+?endValue)?/?2?+?1?,?endValue);
????????????????subTask2.fork();
????????????????return?subTask1.join()?+?subTask2.join();
????????????}
????????}
????}
????public?static?void?main(String[]?args)?throws?ExecutionException,?InterruptedException?{
????????//?Fork/Join框架的線程池
????????ForkJoinPool?pool?=?new?ForkJoinPool();
????????ForkJoinTask?taskFuture?=??pool.submit(new?ForkJoinSubTask(1,1000));
????????Integer?result?=?taskFuture.get();
????????System.out.println("累加結(jié)果是:"?+?result);
????}
}
運行結(jié)果:
...
執(zhí)行子任務(wù)計算:開始值?=?189;結(jié)束值?=?250
執(zhí)行子任務(wù)計算:開始值?=?251;結(jié)束值?=?313
執(zhí)行子任務(wù)計算:開始值?=?314;結(jié)束值?=?375
執(zhí)行子任務(wù)計算:開始值?=?376;結(jié)束值?=?438
執(zhí)行子任務(wù)計算:開始值?=?439;結(jié)束值?=?500
執(zhí)行子任務(wù)計算:開始值?=?501;結(jié)束值?=?563
執(zhí)行子任務(wù)計算:開始值?=?564;結(jié)束值?=?625
執(zhí)行子任務(wù)計算:開始值?=?626;結(jié)束值?=?688
執(zhí)行子任務(wù)計算:開始值?=?689;結(jié)束值?=?750
執(zhí)行子任務(wù)計算:開始值?=?751;結(jié)束值?=?813
執(zhí)行子任務(wù)計算:開始值?=?814;結(jié)束值?=?875
執(zhí)行子任務(wù)計算:開始值?=?876;結(jié)束值?=?938
執(zhí)行子任務(wù)計算:開始值?=?939;結(jié)束值?=?1000
累加結(jié)果是:500500
Java 8 新特性

1.lambada表達式
Lambda 允許把函數(shù)作為一個方法的參數(shù),傳遞到方法中
語法格式:
(parameters)?->?expression?或?(parameters)?->{?statements;?}
代碼示例:
Arrays.asList("jay",?"Eason",?"SHE").forEach(
???????(?String?singer?)?->?System.out.print(?singer?+?",")?);
2. 函數(shù)式接口
Lambda的設(shè)計者為了讓現(xiàn)有的功能與Lambda表達式很好兼容,設(shè)計出函數(shù)式接口。
函數(shù)式接口是指只有一個函數(shù)的接口,可以隱式轉(zhuǎn)換為lambada表達式。 Java 8 提供了注解@FunctionalInterface,顯示聲明一個函數(shù)式接口。 java.lang.Runnable和java.util.concurrent.Callable是函數(shù)式接口的例子~
@FunctionalInterface
public?interface?Runnable?{
????public?abstract?void?run();
}
3. 方法引用
方法引用提供了非常有用的語法,可以直接引用已有Java類或?qū)ο螅▽嵗┑姆椒ɑ驑?gòu)造器。它與Lambda表達式配合使用,可以減少冗余代碼,使代碼更加簡潔。
//利用函數(shù)式接口Consumer的accept方法實現(xiàn)打印,Lambda表達式如下
Consumer?consumer?=?x?->?System.out.println(x);
consumer.accept("jay");
//引用PrintStream類(也就是System.out的類型)的println方法,這就是方法引用
consumer?=?System.out::println;
consumer.accept("關(guān)注公眾號撿田螺的小男孩");
4. 默認方法
默認方法就是一個在接口里面有了一個實現(xiàn)的方法。它允許將新方法添加到接口,但不強制實現(xiàn)了該接口的類必須實現(xiàn)新的方法。
public?interface?ISingerService?{
????//?默認方法
????default?void?sing(){
????????System.out.println("唱歌");
????}
????void?writeSong();
}
//JaySingerServiceImpl?不用強制實現(xiàn)ISingerService的默認sing()方法
public?class?JaySingerServiceImpl?implements?ISingerService?{
????@Override
????public?void?writeSong()?{
????????System.out.println("寫了一首七里香");
????}
}
5.Stream API
Stream API,支持對元素流進行函數(shù)式操作,它集成在Collections API 中,可以對集合進行批量操作。常用API:
filter 篩選 map流映射 reduce 將流中的元素組合起來 collect 返回集合 sorted 排序 flatMap 流轉(zhuǎn)換 limit返回指定流個數(shù) distinct去除重復(fù)元素
public?class?Singer?{
????private?String?name;
????private?Integer?songNum;
????private?Integer?age;
????...
}
List?singerList?=?new?ArrayList();
singerList.add(new?Singer("jay",?11,?36));
singerList.add(new?Singer("eason",?8,?31));
singerList.add(new?Singer("JJ",?6,?29));
List?singerNameList?=?singerList.stream()
????????????????.filter(singer?->?singer.getAge()?>?30)??//篩選年齡大于30
????????????????.sorted(Comparator.comparing(Singer::getSongNum))??//根據(jù)歌曲數(shù)量排序
????????????????.map(Singer::getName)??//提取歌手名字
????????????????.collect(Collectors.toList());?//轉(zhuǎn)換為List
6. Optional
Java 8引入Optional類,用來解決NullPointerException。Optional代替if...else解決空指針問題,使代碼更加簡潔。
if...else 判空
Singer?singer?=?getSingerById("666");
if?(singer?!=?null)?{
????String?name??=?singer.getName();
????System.out.println(name);
}
Optional的判空
Optional?singer?=?Optional.ofNullable(getSingerById("666"));
singer.ifPresent(s?->?System.out.println(s.getName()));
7. Date Time API
JDK 8之前的日期API處理存在非線程安全、時區(qū)處理麻煩等問題。Java 8 在 java.time包下提供了新的日期API,簡化了日期的處理~
LocalDate?today?=?LocalDate.now();
int?year?=?today.getYear();
System.out.println("今年是"?+?year);
//是否閏年
System.out.println("今年是不是閏年:"?+?today.isLeapYear());
LocalDateTime?todayTime?=?LocalDateTime.now();
System.out.println("當(dāng)前時間"?+?todayTime);
//時區(qū)指定
System.out.println("美國時間:"?+?ZonedDateTime.of(todayTime,ZoneId.of("America/Los_Angeles")));
????????
LocalDate?specailDate?=?LocalDate.of(2020,?6,?20);
LocalDate?expectDate?=?specailDate.plus(100,?ChronoUnit.DAYS);
System.out.println("比較特別的一天"?+?specailDate);
System.out.println("特殊日期的100天"?+?expectDate);
8. 重復(fù)注解
重復(fù)注解,即一個注解可以在一個類、屬性或者方法上同時使用多次;用@Repeatable定義重復(fù)注解
@Repeatable(ScheduleTimes.class)
public?@interface?ScheduleTime?{
????String?value();
}
public?@interface?ScheduleTimes?{
????ScheduleTime[]?value();
}
public?class?ScheduleTimeTask?{
????@ScheduleTime("10")
????@ScheduleTime("12")
????public?void?doSomething()?{?}
}
9. Base64
Java 8把Base64編碼的支持加入到官方庫中~
String?str?=?"公眾號:撿田螺的小男孩";
String?encoded?=?Base64.getEncoder().encodeToString(str.getBytes(?StandardCharsets.UTF_8));
String?decoded?=?new?String(Base64.getDecoder().decode(encoded),?StandardCharsets.UTF_8);
10. JVM的新特性
使用元空間Metaspace代替持久代(PermGen space),JVM參數(shù)使用-XX:MetaSpaceSize和-XX:MaxMetaspaceSize設(shè)置大小。
Java 9 新特性

1. java模塊系統(tǒng)
什么是模塊化?
?一個大型系統(tǒng),比如一個商城網(wǎng)站,它會包含很多模塊的,如:訂單模塊,用戶信息模塊,商品信息模塊,廣告位模塊等等。各個模塊之間會相互調(diào)用。如果每個模塊單獨運行都會帶動其他所有模塊,性能非常低效。但是,如果某一模塊運行時,只會啟動它所依賴的模塊,性能大大提升。這就是JDK 9模塊化的思想。
?
什么是JDK 9模塊化?
?Java 平臺模塊系統(tǒng),即Project Jigsaw,把模塊化開發(fā)實踐引入到了Java平臺中。在引入了模塊系統(tǒng)之后,JDK 被重新組織成94個模塊。Java 應(yīng)用可以通過新增的jlink 工具,創(chuàng)建出只包含所依賴的JDK模塊的自定義運行時鏡像。這樣可以極大的減少Java運行時環(huán)境的大小。
?
Java 9 模塊的重要特征:
??
在其工件(artifact)的根目錄中包含了一個描述模塊的 module-info.class 文 件。 工件的格式可以是傳統(tǒng)的 JAR 文件或是 Java 9 新增的 JMOD 文件。 這個文件由根目錄中的源代碼文件 module-info.java 編譯而來。 該模塊聲明文件可以描述模塊的不同特征。
在 module-info.java 文件中,我們可以用新的關(guān)鍵詞module來聲明一個模塊,如下所示。下面給出了一個模塊com.mycompany.mymodule的最基本的模塊聲明
module?com.jay.sample?{???//關(guān)鍵詞module來聲明一個模塊
????exports?com.jay.sample;?//使用?exports可以聲明模塊對其他模塊所導(dǎo)出的包。
????requires?com.jay.common;?//使用requires可以聲明模塊對其他模塊的依賴關(guān)系。
}
2. 不可變集合工廠方法
為了創(chuàng)建不可變集合,JDK9之前醬紫的:
List?stringList?=?new?ArrayList<>();
stringList.add("關(guān)注公眾號:");
stringList.add("撿田螺的小男孩");
List?unmodifiableList?=?Collections.unmodifiableList(stringList);
JDK 9 提供了List.of()、Set.of()、Map.of()和Map.ofEntries()等工廠方法來創(chuàng)建不可變集合:
List?unmodifiableList?=?List.of("關(guān)注公眾號:","撿田螺的小男孩");
3. 接口支持私有方法
JDK 8支持在接口實現(xiàn)默認方法和靜態(tài)方法,但是不能在接口中創(chuàng)建私有方法,為了避免了代碼冗余和提高閱讀性,JDK 9在接口中支持私有方法。
public?interface?IPrivateInterfaceTest?{
????//JDK?7?之前
????String?a?=?"jay";
????void?method7();
????//JDK?8
????default?void?methodDefault8(){
????????System.out.println("JDK?8新特性默認方法");
????}
????static?void?methodStatic8()?{
????????System.out.println("JDk?8新特性靜態(tài)方法");
????}
????
????//Java?9?接口支持私有方法
????private?void?method9(){}
}
4. ?鉆石操作符升級
鉆石操作符是在 java 7 中引入的,可以讓代碼更易讀,但它不能用于匿名的內(nèi)部類。 在 java 9 中, 它可以與匿名的內(nèi)部類一起使用,從而提高代碼的可讀性。
//JDK?5,6
Map?map56?=?new?HashMap();
//JDk?7,8
Map?map78?=?new?HashMap<>();
//JDK?9?結(jié)合匿名內(nèi)部類的實現(xiàn)
Map?map9?=?new?HashMap<>(){};
5. Optional 類改進
java 9 中,java.util.Optional 添加了很多新的有用方法,如:
stream() ifPresentOrElse() or()
ifPresentOrElse 方法的改進就是有了 else,接受兩個參數(shù) Consumer 和 Runnable。
import?java.util.Optional;
?
public?class?OptionalTest?{
???public?static?void?main(String[]?args)?{
??????Optional?optional?=?Optional.of(1);
?
??????optional.ifPresentOrElse(?x?->?System.out.println("Value:?"?+?x),()?->?
?????????System.out.println("Not?Present."));
?
??????optional?=?Optional.empty();
?
??????optional.ifPresentOrElse(?x?->?System.out.println("Value:?"?+?x),()?->?
?????????System.out.println("Not?Present."));
???}??
}
6. 多版本兼容Jar包
?很多公司使用的JDK都是老版本的,JDK6、JDk5 ,甚至JDk4的,不是他們不想升級JDk版本,而是擔(dān)心兼容性問題。JDK 9的一個新特性,多版本兼容Jar包解決了這個問題。舉個例子:假設(shè)你一直用的是小米8,已經(jīng)非常習(xí)慣它的運行流程了,突然出來小米9,即使小米9很多新功能引人入勝,但是有些人不會輕易買小米9,因為已經(jīng)已經(jīng)習(xí)慣小米8的流程。同理,為什么很多公司不升級JDK,就是在此。但是呢,JDK 9的這個功能很強大,它可以讓你的版本升級到JDK 9,但是還是老版本的運行流程,即在老的運行流程繼承新的功能~
?
7. JShell工具
jShell工具相當(dāng)于cmd工具,然后呢,你可以像在cmd工具操作一樣,直接在上面運行Java方法,Java語句等~
jshell>?System.out.println("關(guān)注公眾號:撿田螺的小男孩");
關(guān)注公眾號:撿田螺的小男孩
8. try-with-resources的改進
JDK 9對try-with-resources異常處理機制進行了升級~
//JDK?7,8
try?(BufferedReader?br?=?new?BufferedReader(new?FileReader("d:七里香.txt"))?{
???br.readLine();
}catch(IOException?e){
??log.error("IO?異常,e:{}",e);
}
//JDk?9
BufferedReader?br?=?new?BufferedReader(new?FileReader("d:七里香.txt")
try(br){
??br.readLine();
}catch(IOException?e){
??log.error("IO?異常,e:{}",e);
}
9. Stream API的改進
JDK 9 為Stream API引入以下這些方法,豐富了流處理操作:
takeWhile() dropWhile() iterate ofNullable
「takeWhile」
使用一個斷言(Predicate 接口)作為參數(shù),返回給定Stream的子集直到斷言語句第一次返回 false
//?語法格式
default?Stream?takeWhile(Predicate?super?T>?predicate)
//代碼示例
Stream.of(1,2,3).takeWhile(s->?x<2)
?????????.forEach(System.out::println);?
?//輸出
?1
「dropWhile」
與 takeWhile()作用相反,使用一個斷言(Predicate 接口)作為參數(shù),直到斷言語句第一次返回true,返回給定Stream的子集
//語法
default?Stream?dropWhile(Predicate?super?T>?predicate)
//代碼示例
Stream.of(1,2,3).dropWhile(s->?x<2)
?????????.forEach(System.out::println);
//輸出
2
3
「iterate」
iterate() 方法能夠返回以seed(第一個參數(shù))開頭,匹配 Predicate(第二個參數(shù))直到返回false,并使用第三個參數(shù)生成下一個元素的元素流。
//語法
static??Stream?iterate(T?seed,?Predicate?super?T>?hasNext,?UnaryOperator?next)
//代碼示例
IntStream.iterate(2,?x?->?x?10,?x?->?x*x).forEach(System.out::println);
//輸出
2
4
「ofNullable」
如果指定元素為非null,則獲取一個元素并生成單個元素流,元素為null則返回一個空Stream。
//語法
static??Stream?ofNullable(T?t)
//代碼示例
Stream?s1=?Stream.ofNullable(100);
s1.forEach(System.out::println)
Stream?s2?=?Stream.ofNullable(null);
s2.forEach(System.out::println)
//輸出
100
10.其他
??
HTTP 2客戶端 (支持 WebSocket和 HTTP2 流以及服務(wù)器推送) 進程API(控制和管理操作系統(tǒng)進程) String底層存儲結(jié)構(gòu)更改(char[]替換為byte[]) 標(biāo)識符添加限制( String _ ="hello"不能用) 響應(yīng)式流 API (支持Java 9中的響應(yīng)式編程)
Java 10 新特性

1.局部變量類型推斷
JDK 10增加了局部變量類型推斷(Local-Variable Type Inference)功能,讓 Java 可以像Js里的var一樣可以自動推斷數(shù)據(jù)類型。Java中的var是一個保留類型名稱,而不是關(guān)鍵字。
JDK 10之前
List?list?=?new?ArrayList();
Stream?stream?=?Stream.of(1,?2,?3);
JDK 10 之后
var?list?=?new?ArrayList();?//?ArrayList
var?stream?=??Stream.of(1,?2,?3);
var 變量類型推斷的使用也有局限性,僅「局限」于以下場景:
具有初始化器的局部變量 增強型for循環(huán)中的索引變量 傳統(tǒng)for循環(huán)中聲明的局部變量
而「不能用于」
推斷方法的參數(shù)類型 構(gòu)造函數(shù)參數(shù)類型推斷 推斷方法返回類型 字段類型推斷 捕獲表達式
2. 不可變集合的改進
JDK 10中,List,Set,Map 提供了一個新的靜態(tài)方法copyOf(Collection extends E> coll),它返回Collection集合一個不可修改的副本。
JDK 源碼:
static??List?copyOf(Collection?extends?E>?coll)?{
????return?ImmutableCollections.listCopy(coll);
}
使用實例:
var?oldList?=?new?ArrayList();
oldList.add("歡迎關(guān)注公眾號:");
oldList.add("撿田螺的小男孩");
var?copyList?=?List.copyOf(oldList);
oldList.add("在看、轉(zhuǎn)載、點贊三連");?
copyList.add("雙擊666");??//UnsupportedOperationException異常
3. 并行全垃圾回收器 G1
?JDK 9引入 G1 作為默認垃圾收集器,執(zhí)行GC 時采用的是基于單線程標(biāo)記掃描壓縮算法(mark-sweep-compact)。為了最大限度地減少 Full GC 造成的應(yīng)用停頓的影響,Java 10 中將為 G1 引入多線程并行 GC,同時會使用與年輕代回收和混合回收相同的并行工作線程數(shù)量,從而減少了 Full GC 的發(fā)生,以帶來更好的性能提升、更大的吞吐量。
?
4. 線程本地握手
Java 10 中線程管控引入JVM安全點的概念,將允許在不運行全局JVM安全點的情況下實現(xiàn)線程回調(diào),由線程本身或者JVM線程來執(zhí)行,同時保持線程處于阻塞狀態(tài),這將會很方便使得停止單個線程或不停止線程成為可能。
5. Optional新增orElseThrow()方法
Optional、OptionalDouble等類新增一個方法orElseThrow(),在沒有值時拋出異常
6. 其他新特性
基于 Java 的 實驗性 JIT 編譯器 類數(shù)據(jù)共享 Unicode 語言標(biāo)簽擴展 根證書 基于時間(Time-Based)的版本控制模型
Java 11 新特性

1.字符串操作
String類是Java最常用的類,JDK 11增加了一系列好用的字符串處理方法
isBlank() 判空。 strip() 去除首尾空格 stripLeading() 去除字符串首部空格 stripTrailing() 去除字符串尾部空格 lines() 分割獲取字符串流。 repeat() 復(fù)制字符串
//?判斷字符串是否為空白
"??".isBlank();????//?true
//?去除首尾空格
"?jay?".strip();??//?"jay"
//?去除首部空格?
"?jay?".stripLeading();???//?"jay?"
去除字符串尾部空格
"?jay?".stripLeading();???//?"?jay"
//?行數(shù)統(tǒng)計
"a\nb\nc".lines().count();????//?3
//?復(fù)制字符串
"jay".repeat(3);???//?"jayjayjay"
2.用于 Lambda 參數(shù)的局部變量語法
局部變量類型推斷是Java 10引入的新特性,但是不能在Lambda 表達式中使用。Java 11再次創(chuàng)新,它允許開發(fā)者在 Lambda 表達式中使用 var 進行參數(shù)聲明。
var?map?=?new?HashMap();
map.put("公眾號",?"撿田螺的小男孩");
map.forEach((var?k,?var?v)?->?{
????System.out.println(k?+?":?"?+?v);
});
3.標(biāo)準(zhǔn)化HTTP Client
Java 9 引入Http Client API,Java 10對它更新,Java 11 對它進行標(biāo)準(zhǔn)化。這幾個版本后,Http Client幾乎被完全重寫,支持HTTP/1.1和HTTP/2 ,也支持 websockets。
HttpClient?client?=?HttpClient.newHttpClient();
HttpRequest?request?=?HttpRequest.newBuilder()
????????????.uri(URI.create("https://github.com/whx123/JavaHome"))
????????????.GET()
????????????.build();
//?同步
HttpResponse?response?=?client.send(request,?HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
//?異步
client.sendAsync(request,?HttpResponse.BodyHandlers.ofString())
????.thenApply(HttpResponse::body)
????.thenAccept(System.out::println);
4. 單個命令編譯運行源代碼
Java 11增強了Java 啟動器,使之能夠運行單一文件的Java 源代碼。
Java 11之前,要運行一個 Java 源代碼必須先編譯,再運行
//?編譯
javac?Jay.java
//?運行
java?Jay
Java 11之后,只要一個java命令就搞定
java?Jay.java
5. ZGC:可伸縮低延遲垃圾收集器
ZGC ,即 Z Garbage Collector(垃圾收集器或垃圾回收器)。它是一個可伸縮的、低延遲的垃圾收集器。 ZGC 主要為了滿足如下目標(biāo)進行設(shè)計:
GC 停頓時間不超過 10ms 既能處理幾百 MB 的小堆,也能處理幾個 TB 的大堆 應(yīng)用吞吐能力不會下降超過 15%(與 G1 回收算法相比) 方便在此基礎(chǔ)上引入新的 GC 特性和利用 colord 針以及 Load barriers 優(yōu)化奠定基礎(chǔ) 當(dāng)前只支持 Linux/x64 位平臺
6.其他一些特性
添加 Epsilon 垃圾收集器。 支持 TLS 1.3 協(xié)議 飛行記錄器分析工具 動態(tài)類文件常量 低開銷的 Heap Profiling
Java 12 新特性

1. Switch 表達式擴展(預(yù)覽功能)
傳統(tǒng)的switch語句,容易漏寫break而出錯,同時寫法并不簡潔優(yōu)雅。
Java 12之前
switch?(day)?{
????case?MONDAY:
????case?FRIDAY:
????case?SUNDAY:
????????System.out.println(6);
????????break;
????case?TUESDAY:
????????System.out.println(7);
????????break;
????case?THURSDAY:
????case?SATURDAY:
????????System.out.println(8);
????????break;
????case?WEDNESDAY:
????????System.out.println(9);
????????break;
}
JDk 12 之后,Switch表達式得到增強,能接受語句和表達式。
switch?(day)?{
????case?MONDAY,?FRIDAY,?SUNDAY?->?System.out.println(6);
????case?TUESDAY????????????????->?System.out.println(7);
????case?THURSDAY,?SATURDAY?????->?System.out.println(8);
????case?WEDNESDAY??????????????->?System.out.println(9);
}
2. 緊湊的數(shù)據(jù)格式
JDK 12 新增了NumberFormat對復(fù)雜數(shù)字的格式化
NumberFormat?numberFormat?=?NumberFormat.getCompactNumberInstance(Locale.CHINA,?NumberFormat.Style.SHORT);
System.out.println(numberFormat.format(100000));
//output
10萬
3. 字符串支持transform、indent操作
transform 字符串轉(zhuǎn)換,可以配合函數(shù)式接口Function一起使用
List?list1?=?List.of("jay",?"?撿田螺的小男孩");
List?list2?=?new?ArrayList<>();
list1.forEach(element?->
????????????list2.add(element.transform(String::strip)
????????????????????.transform((e)?->?"Hello,"?+?e))
????);
list2.forEach(System.out::println);
//輸出
Hello,jay
Hello,撿田螺的小男孩
indent 縮進,每行開頭增加空格space和移除空格
String?result?=?"Java\n?Python\nC".indent(3);
System.out.println(result);
//輸出
???Java
????Python
???C
4. Files.mismatch(Path, Path)
Java 12 新增了mismatch方法,此方法返回第一個不匹配的位置,如果沒有不匹配,則返回 -1L。
public?static?long?mismatch(Path?path,?Path?path2)?throws?IOException;
代碼示例:
Path?file1?=?Paths.get("c:\\jay.txt");
Path?file2?=?Paths.get("c:\\撿田螺的小男孩.txt");
try?{
?long?fileMismatch?=?Files.mismatch(file1,?file2);
?System.out.println(fileMismatch);
}?catch?(IOException?e)?{
?e.printStackTrace();
}
5. Teeing Collector
Teeing Collector 是 Streams API 中引入的新的收集器實用程序,它的作用是 merge 兩個 collector 的結(jié)果,API格式如下:
public?static?
????Collector?teeing(Collector?super?T,??,?R1>?downstream1,
????Collector?super?T,??,?R2>?downstream2,
????BiFunction?super?R1,???super?R2,?R>?merger)
直接看代碼例子吧,如下為求學(xué)生的平均分和總分的例子
??List?studentList=?Arrays.asList(
????????????????new?Student("jay",?90),
????????????????new?Student("撿田螺的小男孩",?100),
????????????????new?Student("撿表情的小男孩",?80)
????????);
????????String?teeingResult=studentList.stream().collect(
????????????????Collectors.teeing(
????????????????????????Collectors.averagingInt(Student::getScore),
????????????????????????Collectors.summingInt(Student::getScore),
????????????????????????(s1,s2)->?s1+?":"+?s2
????????????????)
????????);
?System.out.println(teeingResult);?//90:270
6.其他特性
支持unicode 11(684個新字符、11個新blocks、7個新腳本) JVM 常量 API (主要在新的java.lang.invoke.constant包中定義了一系列基于值的符號引用類型,能夠描述每種可加載常量。) Shenandoah GC(低暫停時間垃圾收集器) G1 收集器提升 (可中止的混合收集集合、及時返回未使用的已分配內(nèi)存) 默認CDS檔案 JMH 基準(zhǔn)測試
Java 13 新特性

Switch 表達式擴展(引入 yield 關(guān)鍵字)
傳統(tǒng)的switch:
private?static?String?getText(int?number)?{
????String?result?=?"";
????switch?(number)?{
????????case?1,?2:
????????result?=?"one?or?two";
????????break;
????????case?3:
????????result?=?"three";
????????break;
????????case?4,?5,?6:
????????result?=?"four?or?five?or?six";
????????break;
????????default:
????????result?=?"unknown";
????????break;
Java 13之后,value break 語句不再被編譯,而是用 yield 來進行值返回
private?static?String?getText(int?number)?{
????return?switch?(number)?{
????????case?1,?2:
????????????yield?"one?or?two";
????????case?3:
????????????yield?"three";
????????case?4,?5,?6:
????????????yield?"four?or?five?or?six";
????????default:
????????????yield?"unknown";
????};
}
2.文本塊升級
Java 13之前,字符串不能夠多行使用,需要通過換行轉(zhuǎn)義或者換行連接符等等,反正就是好麻煩、好難維護。
String?html?=?"\n"?+
??????????????"????\n"?+
??????????????"????????Hello,?撿田螺的小男孩
\n"?+
??????????????"????\n"?+
??????????????"\n";
Java 13之后,清爽多了~
String?html?=?"""
????????????????
????????????????????
????????????????????????Hello,??撿田螺的小男孩
????????????????????
????????????????
????????????????""";
3. SocketAPI 重構(gòu)
傳統(tǒng)的Java Socket API(java.net.ServerSocket 和 java.net.Socket)依賴于SocketImpl 的內(nèi)部實現(xiàn) 在 Java 13之前,通過使用 PlainSocketImpl 作為 SocketImpl 的具體實現(xiàn)。 Java 13 中的新底層實現(xiàn),引入 NioSocketImpl 的實現(xiàn)用以替換 SocketImpl 的 PlainSocketImpl 實現(xiàn),此實現(xiàn)與 NIO(新 I/O)實現(xiàn)共享相同的內(nèi)部基礎(chǔ)結(jié)構(gòu),并且與現(xiàn)有的緩沖區(qū)高速緩存機制集成在一起。
一個Socket簡單例子:
import?java.io.IOException;
import?java.net.ServerSocket;
import?java.net.Socket;
public?class?SocketAPITest?{
????public?static?void?main(String[]?args)?{
????????try?(ServerSocket?serverSocket?=?new?ServerSocket(8080)){
????????????boolean?runFlag?=?true;
????????????while(runFlag){
????????????????Socket?clientSocket?=?serverSocket.accept();
????????????????//搞事情
????????????}
????????}?catch?(IOException?e)?{
????????????e.printStackTrace();
????????}
????}
}
運行以上的實例,看下是否有以下關(guān)鍵詞輸出~
[class,load]?sun.nio.ch.NioSocketImpl
4.FileSystems.newFileSystem新方法
FileSystems 類中添加了以下三種新方法,以便更容易地使用將文件內(nèi)容視為文件系統(tǒng)的文件系統(tǒng)提供程序:
1、newFileSystem(Path) 2、newFileSystem(Path, Map ) 3、newFileSystem(Path, Map , ClassLoader)
5. 增強 ZGC 釋放未使用內(nèi)存
ZGC 是Java 11 中引入的最為矚目的垃圾回收特性,是一種可伸縮、低延遲的垃圾收集器。但是實際使用中,它不能夠主動將未使用的內(nèi)存釋放給操作系統(tǒng)。 Java 13 中對 ZGC 的改進,包括釋放未使用內(nèi)存給操作系統(tǒng)、支持最大堆大小為 16TB、JVM參數(shù)-XX:SoftMaxHeapSize 來軟限制堆大小
6.其他特性
動態(tài) CDS 存檔, 擴展了 Java 10 中引入的類數(shù)據(jù)共享功能, 使用CDS 存檔變得更容易。 文本塊的字符串類新方法,如formatted(Object…args),stripIndent()等。
Java 14 新特性

1. instanceof模式匹配
instanceof 傳統(tǒng)使用方式:
if?(person?instanceof?Singer)?{
????Singer?singer?=?(Singer)?person;
????singer.sing();
}?else?if?(person?instanceof?Writer)?{
????Writer?writer?=?(Writer)?person;
????writer.write();
}
Java 14 對 instanceof 進行模式匹配改進之后
if?(person?instanceof?Singer?singer)?{
????singer.sing();
}?else?if?(person?instanceof?Writer?writer)?{
???writer.write();
}
2.Record 類型(預(yù)覽功能)
Java 14將Record 類型作為預(yù)覽特性而引入,有點類似于Lombok 的@Data注解,看個例子吧:
public?record?Person(String?name,?int?age)?{
????public?static?String?address;
????public?String?getName()?{
????????return?name;
????}
}
反編譯結(jié)果:
public?final?class?Person?extends?java.lang.Record?{
????private?final?java.lang.String?name;
????private?final?java.lang.String?age;
????public?Person(java.lang.String?name,?java.lang.String?age)?{?/*?compiled?code?*/?}
????public?java.lang.String?getName()?{?/*?compiled?code?*/?}
????public?java.lang.String?toString()?{?/*?compiled?code?*/?}
????public?final?int?hashCode()?{?/*?compiled?code?*/?}
????public?final?boolean?equals(java.lang.Object?o)?{?/*?compiled?code?*/?}
????public?java.lang.String?name()?{?/*?compiled?code?*/?}
????public?java.lang.String?age()?{?/*?compiled?code?*/?}
}
可以發(fā)現(xiàn),當(dāng)用 Record 來聲明一個類時,該類將自動擁有下面特征:
構(gòu)造方法 hashCode() 方法 euqals() 方法 toString() 方法 類對象被final 關(guān)鍵字修飾,不能被繼承。
3. Switch 表達式-標(biāo)準(zhǔn)化
switch 表達式在之前的 Java 12 和 Java 13 中都是處于預(yù)覽階段,終于在 Java 14 標(biāo)準(zhǔn)化,成為穩(wěn)定版本。
Java 12 為switch 表達式引入Lambda 語法 Java 13 使用yield代替 break 關(guān)鍵字來返回表達式的返回值。
String?result?=?switch?(day)?{
????case?"M",?"W",?"F"?->?"MWF";
????case?"T",?"TH",?"S"?->?"TTS";
????default?->?{
????????if?(day.isEmpty())?{
????????????yield?"Please?insert?a?valid?day.";
????????}?else?{
????????????yield?"Looks?like?a?Sunday.";
????????}
????}
};
System.out.println(result);
4. 改進 NullPointerExceptions提示信息
Java 14 之前:
String?name?=?song.getSinger().getSingerName()
?
//堆棧信息
Exception?in?thread?"main"?java.lang.NullPointerException
????at?NullPointerExample.main(NullPointerTest.java:6)
Java 14,通過引入JVM 參數(shù)-XX:+ShowCodeDetailsInExceptionMessages,可以在空指針異常中獲取更為詳細的調(diào)用信息。
Exception?in?thread?"main"?java.lang.NullPointerException:?Cannot?invoke?"Singer.getSingerName()"?
because?the?return?value?of?"rainRow.getSinger()"?is?null
????at?NullPointerExample.main(NullPointerTest.java:6)
5. 其他特性
G1 的 NUMA 可識別內(nèi)存分配 刪除 CMS 垃圾回收器 GC 支持 MacOS 和 Windows 系統(tǒng)
Java 15 新特性


1.EdDSA 數(shù)字簽名算法
使用 Edwards-Curve 數(shù)字簽名算法(EdDSA)實現(xiàn)加密簽名。 與其它簽名方案相比,EdDSA 具有更高的安全性和性能。 得到許多其它加密庫(如 OpenSSL、BoringSSL)的支持。
2.Sealed Classes(封閉類,預(yù)覽)
封閉類,可以是封閉類、封閉接口,防止其他類或接口擴展或?qū)崿F(xiàn)它們。
public?abstract?sealed?class?Singer
????permits?Jay,?Eason{
????...
}
類Singer被sealed 修飾,是封閉類,只能被2個指定子類(Jay, Eason)繼承。
3. Hidden Classes(隱藏類)
隱藏類天生為框架設(shè)計的。 隱藏類只能通過反射訪問,不能直接被其他類的字節(jié)碼。
4. Remove the Nashorn JavaScript Engine
Nashorn太難維護了,移除 Nashorn JavaScript引擎成為一種必然 其實早在JDK 11 中就已經(jīng)被標(biāo)記為 deprecated 了。
5.Reimplement the Legacy DatagramSocket API(重新實現(xiàn)DatagramSocket API)
重新實現(xiàn)老的DatagramSocket API 更改java.net.DatagramSocket 和 java.net.MulticastSocket 為更加簡單、現(xiàn)代化的底層實現(xiàn)。
6.其他
Disable and Deprecate Biased Locking(準(zhǔn)備禁用偏向鎖) instanceof 自動匹配模式(預(yù)覽) ZGC,一個可伸縮、低延遲的垃圾回收器。(轉(zhuǎn)正) Text Blocks,文本功能轉(zhuǎn)正(JDK 13和14預(yù)覽,14終于轉(zhuǎn)正) Remove the Solaris and SPARC Ports(刪除 Solaris 和 SPARC 端口) 外部存儲器訪問 API(允許Java 應(yīng)用程序安全有效地訪問 Java 堆之外的外部內(nèi)存。) Record類型二次預(yù)覽(在Java 14就預(yù)覽過啦)
參考與感謝
JDK6 新特性[1] Java 7的新功能[2] Java 9 新特性概述[3] Java 9 新特性[4] Java 10 新特性介紹[5] Java 11 新特性介紹[6] Java 13 新特性概述[7] Java 14 新特性概述[8] JDK/Java 15發(fā)布 Java 15 正式發(fā)布, 14 個新特性,刷新你的認知??!
Reference
JDK6 新特性: https://blog.csdn.net/weixin_40926603/article/details/84970283
[2]Java 7的新功能: https://stackoverflow.com/questions/213958/new-features-in-java-7
[3]Java 9 新特性概述: https://developer.ibm.com/zh/articles/the-new-features-of-Java-9/
[4]Java 9 新特性: https://www.runoob.com/java/java9-new-features.html
[5]Java 10 新特性介紹: https://developer.ibm.com/zh/technologies/java/articles/the-new-features-of-java-10/
[6]Java 11 新特性介紹: https://developer.ibm.com/zh/technologies/java/articles/the-new-features-of-java-11/
[7]Java 13 新特性概述: https://developer.ibm.com/zh/technologies/java/articles/the-new-features-of-java-13/
[8]Java 14 新特性概述: https://developer.ibm.com/zh/technologies/java/articles/the-new-features-of-java-14/
點個?在看?
