<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java程序員必備基礎(chǔ):JDK 5-15都有哪些經(jīng)典新特性

          共 6861字,需瀏覽 14分鐘

           ·

          2021-01-14 22:06

          前言

          JDK 15發(fā)布啦~ 我們一起回顧JDK 5-15 的新特性吧,大家一起學(xué)習(xí)哈~

          本文已經(jīng)收錄到github

          ?

          https://github.com/whx123/JavaHome

          ?

          「公眾號(hào):撿田螺的小男孩」

          Java 5 新特性

          1. 泛型

          泛型本質(zhì)是參數(shù)化類(lèi)型,解決不確定具體對(duì)象類(lèi)型的問(wèn)題。

          ?List?strList=new?ArrayList();

          2. 增強(qiáng)循環(huán)(for-each)

          for-each循環(huán)簡(jiǎn)化了集合的遍歷。

          String?[]?str?=?{"關(guān)注","公眾號(hào)","撿田螺的小男孩"};
          for?(String?temp:str)?{
          ?????System.out.println(temp);
          }

          3. 自動(dòng)封箱拆箱

          • 自動(dòng)裝箱: 就是將基本數(shù)據(jù)類(lèi)型自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的包裝類(lèi)。
          • 自動(dòng)拆箱:就是將包裝類(lèi)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的基本數(shù)據(jù)類(lèi)型。

          包裝類(lèi)型有:Integer,Double,Float,Long,Short,Character和Boolean

          Integer?i?=666;??//自動(dòng)裝箱
          int?a=?i;?????//自動(dòng)拆箱

          4. 枚舉

          關(guān)鍵字enum可以將一組具名的值的有限集合創(chuàng)建為一種新的類(lèi)型,而這些具名的值可以作為常規(guī)的程序組件使用,這就是枚舉類(lèi)型。

          enum?SeasonEnum?{
          ????SPRING,SUMMER,FALL,WINTER;
          }

          5. 可變參數(shù)

          我們?cè)诙x方法參數(shù)的時(shí)候不確定定義多少個(gè),就可以定義為「可變參數(shù)」,它本質(zhì)上是一個(gè)「數(shù)組」

          public?static?void?main(String[]?args)?throws?Exception?{
          ????String?[]?str?=?{"關(guān)注","公眾號(hào)","撿田螺的小男孩"};
          ????testVarargs(str);
          ????String?str1?=?"關(guān)注公眾號(hào),撿田螺的小男孩";
          ????testVarargs(str1);
          }
          //可變參數(shù)String...?args
          private?static?void?testVarargs(String...?args)?{
          ????for?(String?arg?:?args)?{
          ????????System.out.println(arg);
          ????}
          }

          6. 注解

          可以把注解理解為代碼里的特殊標(biāo)記,這些標(biāo)記可以在編譯,類(lèi)加載,運(yùn)行時(shí)被讀取,并執(zhí)行相應(yīng)的處理。

          @Target(ElementType.METHOD)
          @Retention(RetentionPolicy.SOURCE)
          public?@interface?Override?{
          }

          7.靜態(tài)導(dǎo)入

          通過(guò)import static類(lèi),就可以使用類(lèi)里的靜態(tài)變量或方法。看一下例子哈~

          import?static?java.lang.System.out;?//靜態(tài)導(dǎo)入System類(lèi)的靜態(tài)變量out
          public?class?Test?{
          ????public?static?void?main(String[]?args)?throws?Exception?{
          ????????String?str1?=?"關(guān)注公眾號(hào),撿田螺的小男孩";
          ????????System.out.println(str1);?//常規(guī)寫(xiě)法
          ????????out.println(str1);??//靜態(tài)導(dǎo)入,可以直接使用out輸出
          ????}
          }

          8. 線程并發(fā)庫(kù)(JUC)

          JDK5 豐富了線程處理功能,java.util.concurrent包提供了以下的類(lèi)、接口:

          ?
          • 線程池:ExecutorService接口
          • 線程護(hù)斥:Lock 類(lèi)
          • 線程通信:Condition接口
          • 同步隊(duì)列:ArrayBlockingQueue類(lèi)
          • 同步集合:ConcurrentHashMap類(lèi)
          ?

          Java 6 新特性

          1.Desktop類(lèi)和SystemTray類(lèi)

          JDK 6在java.awt包下,新增了兩個(gè)類(lèi):Desktop類(lèi)和SystemTray類(lèi)

          ?
          • 「Desktop類(lèi)」: 用來(lái)打開(kāi)系統(tǒng)默認(rèn)瀏覽器瀏覽指定的URL,打開(kāi)系統(tǒng)默認(rèn)郵件客戶端發(fā)郵件等
          • 「SystemTray類(lèi)」:用來(lái)在系統(tǒng)托盤(pán)區(qū)創(chuàng)建一個(gè)托盤(pán)程序,如果在微軟的Windows上,它被稱為“任務(wù)欄”狀態(tài)區(qū)域。
          ?
          //獲取Desktop實(shí)例
          Desktop?desktop?=?Desktop.getDesktop();
          desktop.browse(URI.create("https://www.baidu.com"));

          2. 使用JAXB2來(lái)實(shí)現(xiàn)對(duì)象與XML之間的映射

          JAXB,即Java Architecture for XML Binding,可以實(shí)現(xiàn)對(duì)象與XML之間的映射,常用注解如下:

          ?
          • @XmlRootElement:注解在類(lèi)上面,對(duì)應(yīng)xml的跟元素,使用name屬性定義根節(jié)點(diǎn)的名稱。
          • @XmlElement:指定一個(gè)字段或get/set方法映射到xml的節(jié)點(diǎn),使用name屬性定義這個(gè)根節(jié)點(diǎn)的名稱。
          • @XmlAttribute:將JavaBean對(duì)象的屬性映射為xml的屬性,使用name屬性為生成的xml屬性指定別名。
          • @XmlAccessorType:定義映射這個(gè)類(lèi)中的何種類(lèi)型都需要映射到xml。
          • @XmlSchema: 將包映射到XML名稱空間
          ?

          「看個(gè)例子吧~」

          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;
          ????}
          }

          「運(yùn)行效果:」

          "1.0"?encoding="GBK"?standalone="yes"?>

          ????"8"?name="jay"/>
          ????"10"?name="eason"/>

          3.輕量級(jí) Http Server API

          JDK 6中提供了簡(jiǎn)單的Http Server API,可以構(gòu)建嵌入式Http服務(wù)器,同時(shí)支持Http和Https協(xié)議。HttpServer會(huì)調(diào)用HttpHandler實(shí)現(xiàn)類(lèi)的回調(diào)方法來(lái)處理客戶端請(qǐng)求,這里用戶只需實(shí)現(xiàn)HttpHandler接口就可以了。

          /**
          ?*?根據(jù)Java提供的API實(shí)現(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請(qǐng)求交給MyHandler處理器處理
          ????????httpServer.createContext("/",?new?MyHandler());
          ????????httpServer.start();
          ????}
          }

          public?class?MyHandler?implements?HttpHandler?{

          ????public?void?handle(HttpExchange?httpExchange)?throws?IOException?{
          ????????//請(qǐng)求頭
          ????????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)信息的長(zhǎng)度
          ????????httpExchange.sendResponseHeaders(200,?response.length());
          ????????//獲得輸出流
          ????????OutputStream?os?=?httpExchange.getResponseBody();
          ????????os.write(response.toString().getBytes());
          ????????os.close();
          ????}
          }

          4. 插入式注解處理API

          ?

          JDK 6提供了插入式注解處理API,可以讓我們定義的注解在編譯期而不是運(yùn)行期生效,從而可以在編譯期修改字節(jié)碼。lombok框架就是使用該特性來(lái)實(shí)現(xiàn)的,Lombok通過(guò)注解的方式,在編譯時(shí)自動(dòng)為屬性生成構(gòu)造器、getter/setter、equals、hashcode、toString等方法,大大簡(jiǎn)化了代碼的開(kāi)發(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);
          ????}
          }

          「運(yùn)行結(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ù)都會(huì)用Annotation部分代替XML文件來(lái)配置運(yùn)行參數(shù)。

          ?

          以下列舉Common Annotations 1.0里面的幾個(gè)Annotations:

          • @Generated:用于標(biāo)注生成的源代碼
          • @Resource: 用于標(biāo)注所依賴的資源,容器據(jù)此注入外部資源依賴,有基于字段的注入和基于setter方法的注入兩種方式 。
          • @Resources:同時(shí)標(biāo)注多個(gè)外部依賴,容器會(huì)把所有這些外部依賴注入
          • @PostConstruct:標(biāo)注當(dāng)容器注入所有依賴之后運(yùn)行的方法,用來(lái)進(jìn)行依賴注入后的初始化工作,只有一個(gè)方法可以標(biāo)注為PostConstruct 。
          • @PreDestroy:當(dāng)對(duì)象實(shí)例將要被從容器當(dāng)中刪掉之前,要執(zhí)行的回調(diào)方法要標(biāo)注為PreDestroy

          7. Compiler API

          javac編譯器可以把.java的源文件編譯為.class文件,JDK 6的新特性Compiler API(JSR 199)也可以動(dòng)態(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?javaFileObjects?=?standardJavaFileManager.getJavaFileObjects("C:\\Singer.java");
          ????????javaCompiler.getTask(null,?standardJavaFileManager,?null,?null,?null,?javaFileObjects).call();
          ????????standardJavaFileManager.close();
          ????}
          }

          運(yùn)行結(jié)果:會(huì)在C目錄生成Singer.class文件

          8. 對(duì)腳本語(yǔ)言的支持(如: ruby, groovy, javascript)

          JDK6增加了對(duì)腳本語(yǔ)言的支持(JSR 223),原理是將腳本語(yǔ)言編譯成字節(jié)碼,這樣腳本語(yǔ)言也能享用Java平臺(tái)的諸多優(yōu)勢(shì),包括可移植性,安全等。JDK6實(shí)現(xiàn)包含了一個(gè)基于Mozilla Rhino的 腳本語(yǔ)言引擎,因此可以支持javascript,當(dāng)然JDK也支持ruby等其他語(yǔ)言

          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字符串類(lèi)型。

          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,資源自動(dòng)關(guān)閉

          JDK 7 之前:

          BufferedReader?br?=?new?BufferedReader(new?FileReader("d:七里香.txt"));
          try?{
          ???return?br.readLine();
          }?finally?{
          ???br.close();
          }

          JDK 7 之后:

          /*
          ?*?聲明在try括號(hào)中的對(duì)象稱為資源,在方法執(zhí)行完畢后會(huì)被自動(dòng)關(guān)閉
          ?*/
          try?(BufferedReader?br?=?new?BufferedReader(new?FileReader("d:七里香.txt"))?{
          ???return?br.readLine();
          }

          3. 整數(shù)類(lèi)型如(byte,short,int,long)能夠用二進(jìn)制來(lái)表示

          //0b或者0B表示二進(jìn)制
          int?a?=?0b010;
          int?b?=?0B010;

          4. 數(shù)字常量支持下劃線

          int?a?=?11_11;//a的值為1111,下劃線不影響實(shí)際值,提升可讀性

          5. 泛型實(shí)例化類(lèi)型自動(dòng)推斷,即”<>”

          JDK 7 之前:

          Map>?map?=?new?HashMap>();

          JDK 7之后:

          //不須聲明類(lèi)型,自動(dòng)根據(jù)前面<>推斷其類(lèi)型
          Map>?map?=?new?HashMap<>();

          6.一個(gè)catch中捕獲多個(gè)異常類(lèi)型,用(|)分隔開(kāi)

          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. 增強(qiáng)的文件系統(tǒng)

          Java7 提供了全新的NIO2.0 API,方便文件管理的編碼。如,可以在java.nio.file包下使用Path、Paths、Files、WatchService等常用類(lèi)型。

          Path?path?=?Paths.get("C:\\jay\\七里香.txt");?//創(chuàng)建Path對(duì)象
          byte[]?bytes=?Files.readAllBytes(path);??//讀取文件
          System.out.println(path.getFileName());?//獲取當(dāng)前文件名稱
          System.out.println(path.toAbsolutePath());?//?獲取文件絕對(duì)路徑
          System.out.println(new?String(bytes,?"utf-8"));

          8. Fork/join 框架

          Java7提供的一個(gè)用于并行執(zhí)行任務(wù)的框架,是一個(gè)把大任務(wù)分割成若干個(gè)小任務(wù),最終匯總每個(gè)小任務(wù)結(jié)果后得到大任務(wù)結(jié)果的框架。

          Fork/join計(jì)算1-1000累加值:

          public?class?ForkJoinPoolTest?{

          ????private?static?final?Integer?DURATION_VALUE?=?100;

          ????static?class?ForkJoinSubTask?extends?RecursiveTask{

          ????????//?子任務(wù)開(kāi)始計(jì)算的值
          ????????private?Integer?startValue;
          ????????//?子任務(wù)結(jié)束計(jì)算的值
          ????????private?Integer?endValue;

          ????????private?ForkJoinSubTask(Integer?startValue?,?Integer?endValue)?{
          ????????????this.startValue?=?startValue;
          ????????????this.endValue?=?endValue;
          ????????}

          ????????@Override
          ????????protected?Integer?compute()?{
          ????????????//小于一定值DURATION,才開(kāi)始計(jì)算
          ????????????if(endValue?-?startValue?????????????????System.out.println("執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?"?+?startValue?+?";結(jié)束值?=?"?+?endValue);
          ????????????????Integer?totalValue?=?0;
          ????????????????for?(int?index?=?this.startValue;?index?<=?this.endValue;?index++)?{
          ????????????????????totalValue?+=?index;
          ????????????????}
          ????????????????return?totalValue;
          ????????????}?else?{
          ????????????????//?將任務(wù)拆分,拆分成兩個(gè)任務(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);

          ????}
          }

          運(yùn)行結(jié)果:

          ...
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?189;結(jié)束值?=?250
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?251;結(jié)束值?=?313
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?314;結(jié)束值?=?375
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?376;結(jié)束值?=?438
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?439;結(jié)束值?=?500
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?501;結(jié)束值?=?563
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?564;結(jié)束值?=?625
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?626;結(jié)束值?=?688
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?689;結(jié)束值?=?750
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?751;結(jié)束值?=?813
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?814;結(jié)束值?=?875
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?876;結(jié)束值?=?938
          執(zhí)行子任務(wù)計(jì)算:開(kāi)始值?=?939;結(jié)束值?=?1000
          累加結(jié)果是:500500

          Java 8 新特性

          1.lambada表達(dá)式

          Lambda 允許把函數(shù)作為一個(gè)方法的參數(shù),傳遞到方法中

          語(yǔ)法格式:

          (parameters)?->?expression?或?(parameters)?->{?statements;?}

          代碼示例:

          Arrays.asList("jay",?"Eason",?"SHE").forEach(
          ???????(?String?singer?)?->?System.out.print(?singer?+?",")?);

          2. 函數(shù)式接口

          Lambda的設(shè)計(jì)者為了讓現(xiàn)有的功能與Lambda表達(dá)式很好兼容,設(shè)計(jì)出函數(shù)式接口。

          • 函數(shù)式接口是指只有一個(gè)函數(shù)的接口,可以隱式轉(zhuǎn)換為lambada表達(dá)式。
          • Java 8 提供了注解@FunctionalInterface,顯示聲明一個(gè)函數(shù)式接口。
          • java.lang.Runnable和java.util.concurrent.Callable是函數(shù)式接口的例子~
          @FunctionalInterface
          public?interface?Runnable?{
          ????public?abstract?void?run();
          }

          3. 方法引用

          方法引用提供了非常有用的語(yǔ)法,可以直接引用已有Java類(lèi)或?qū)ο螅▽?shí)例)的方法或構(gòu)造器。它與Lambda表達(dá)式配合使用,可以減少冗余代碼,使代碼更加簡(jiǎn)潔。

          //利用函數(shù)式接口Consumer的accept方法實(shí)現(xiàn)打印,Lambda表達(dá)式如下
          Consumer?consumer?=?x?->?System.out.println(x);
          consumer.accept("jay");
          //引用PrintStream類(lèi)(也就是System.out的類(lèi)型)的println方法,這就是方法引用
          consumer?=?System.out::println;
          consumer.accept("關(guān)注公眾號(hào)撿田螺的小男孩");

          4. 默認(rèn)方法

          默認(rèn)方法就是一個(gè)在接口里面有了一個(gè)實(shí)現(xiàn)的方法。它允許將新方法添加到接口,但不強(qiáng)制實(shí)現(xiàn)了該接口的類(lèi)必須實(shí)現(xiàn)新的方法。

          public?interface?ISingerService?{
          ????//?默認(rèn)方法
          ????default?void?sing(){
          ????????System.out.println("唱歌");
          ????}
          ????void?writeSong();
          }

          //JaySingerServiceImpl?不用強(qiáng)制實(shí)現(xiàn)ISingerService的默認(rèn)sing()方法
          public?class?JaySingerServiceImpl?implements?ISingerService?{
          ????@Override
          ????public?void?writeSong()?{
          ????????System.out.println("寫(xiě)了一首七里香");
          ????}
          }

          5.Stream API

          Stream API,支持對(duì)元素流進(jìn)行函數(shù)式操作,它集成在Collections API 中,可以對(duì)集合進(jìn)行批量操作。常用API:

          • filter 篩選
          • map流映射
          • reduce 將流中的元素組合起來(lái)
          • collect 返回集合
          • sorted 排序
          • flatMap 流轉(zhuǎn)換
          • limit返回指定流個(gè)數(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)換為L(zhǎng)ist

          6. Optional

          Java 8引入Optional類(lèi),用來(lái)解決NullPointerException。Optional代替if...else解決空指針問(wèn)題,使代碼更加簡(jiǎn)潔。

          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處理存在非線程安全、時(shí)區(qū)處理麻煩等問(wèn)題。Java 8 在 java.time包下提供了新的日期API,簡(jiǎn)化了日期的處理~

          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)前時(shí)間"?+?todayTime);
          //時(shí)區(qū)指定
          System.out.println("美國(guó)時(shí)間:"?+?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ù)注解,即一個(gè)注解可以在一個(gè)類(lèi)、屬性或者方法上同時(shí)使用多次;用@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編碼的支持加入到官方庫(kù)中~

          String?str?=?"公眾號(hào):撿田螺的小男孩";
          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)

          什么是模塊化?

          ?

          一個(gè)大型系統(tǒng),比如一個(gè)商城網(wǎng)站,它會(huì)包含很多模塊的,如:訂單模塊,用戶信息模塊,商品信息模塊,廣告位模塊等等。各個(gè)模塊之間會(huì)相互調(diào)用。如果每個(gè)模塊單獨(dú)運(yùn)行都會(huì)帶動(dòng)其他所有模塊,性能非常低效。但是,如果某一模塊運(yùn)行時(shí),只會(huì)啟動(dòng)它所依賴的模塊,性能大大提升。這就是JDK 9模塊化的思想。

          ?

          什么是JDK 9模塊化?

          ?

          Java 平臺(tái)模塊系統(tǒng),即Project Jigsaw,把模塊化開(kāi)發(fā)實(shí)踐引入到了Java平臺(tái)中。在引入了模塊系統(tǒng)之后,JDK 被重新組織成94個(gè)模塊。Java 應(yīng)用可以通過(guò)新增的jlink 工具,創(chuàng)建出只包含所依賴的JDK模塊的自定義運(yùn)行時(shí)鏡像。這樣可以極大的減少Java運(yùn)行時(shí)環(huán)境的大小。

          ?

          Java 9 模塊的重要特征:

          ?
          • 在其工件(artifact)的根目錄中包含了一個(gè)描述模塊的 module-info.class 文 件。
          • 工件的格式可以是傳統(tǒng)的 JAR 文件或是 Java 9 新增的 JMOD 文件。
          • 這個(gè)文件由根目錄中的源代碼文件 module-info.java 編譯而來(lái)。
          • 該模塊聲明文件可以描述模塊的不同特征。
          ?

          在 module-info.java 文件中,我們可以用新的關(guān)鍵詞module來(lái)聲明一個(gè)模塊,如下所示。下面給出了一個(gè)模塊com.mycompany.mymodule的最基本的模塊聲明

          module?com.jay.sample?{???//關(guān)鍵詞module來(lái)聲明一個(gè)模塊
          ????exports?com.jay.sample;?//使用?exports可以聲明模塊對(duì)其他模塊所導(dǎo)出的包。
          ????requires?com.jay.common;?//使用requires可以聲明模塊對(duì)其他模塊的依賴關(guān)系。
          }

          2. 不可變集合工廠方法

          為了創(chuàng)建不可變集合,JDK9之前醬紫的:

          List?stringList?=?new?ArrayList<>();
          stringList.add("關(guān)注公眾號(hào):");
          stringList.add("撿田螺的小男孩");
          List?unmodifiableList?=?Collections.unmodifiableList(stringList);

          JDK 9 提供了List.of()、Set.of()、Map.of()和Map.ofEntries()等工廠方法來(lái)創(chuàng)建不可變集合:

          List?unmodifiableList?=?List.of("關(guān)注公眾號(hào):","撿田螺的小男孩");

          3. 接口支持私有方法

          JDK 8支持在接口實(shí)現(xiàn)默認(rè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新特性默認(rèn)方法");
          ????}
          ????static?void?methodStatic8()?{
          ????????System.out.println("JDk?8新特性靜態(tài)方法");
          ????}
          ????
          ????//Java?9?接口支持私有方法
          ????private?void?method9(){}
          }

          4. ?鉆石操作符升級(jí)

          • 鉆石操作符是在 java 7 中引入的,可以讓代碼更易讀,但它不能用于匿名的內(nèi)部類(lèi)。
          • 在 java 9 中, 它可以與匿名的內(nèi)部類(lèi)一起使用,從而提高代碼的可讀性。
          //JDK?5,6
          Map?map56?=?new?HashMap();
          //JDk?7,8
          Map?map78?=?new?HashMap<>();
          //JDK?9?結(jié)合匿名內(nèi)部類(lèi)的實(shí)現(xiàn)
          Map?map9?=?new?HashMap<>(){};

          5. Optional 類(lèi)改進(jìn)

          java 9 中,java.util.Optional 添加了很多新的有用方法,如:

          • stream()
          • ifPresentOrElse()
          • or()

          ifPresentOrElse 方法的改進(jìn)就是有了 else,接受兩個(gè)參數(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的,不是他們不想升級(jí)JDk版本,而是擔(dān)心兼容性問(wèn)題。JDK 9的一個(gè)新特性,多版本兼容Jar包解決了這個(gè)問(wèn)題。舉個(gè)例子:假設(shè)你一直用的是小米8,已經(jīng)非常習(xí)慣它的運(yùn)行流程了,突然出來(lái)小米9,即使小米9很多新功能引人入勝,但是有些人不會(huì)輕易買(mǎi)小米9,因?yàn)橐呀?jīng)已經(jīng)習(xí)慣小米8的流程。同理,為什么很多公司不升級(jí)JDK,就是在此。但是呢,JDK 9的這個(gè)功能很強(qiáng)大,它可以讓你的版本升級(jí)到JDK 9,但是還是老版本的運(yùn)行流程,即在老的運(yùn)行流程繼承新的功能~

          ?

          7. JShell工具

          jShell工具相當(dāng)于cmd工具,然后呢,你可以像在cmd工具操作一樣,直接在上面運(yùn)行Java方法,Java語(yǔ)句等~

          jshell>?System.out.println("關(guān)注公眾號(hào):撿田螺的小男孩");
          關(guān)注公眾號(hào):撿田螺的小男孩

          8. try-with-resources的改進(jìn)

          JDK 9對(duì)try-with-resources異常處理機(jī)制進(jìn)行了升級(jí)~

          //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的改進(jìn)

          JDK 9 為Stream API引入以下這些方法,豐富了流處理操作:

          • takeWhile()
          • dropWhile()
          • iterate
          • ofNullable

          「takeWhile」

          使用一個(gè)斷言(Predicate 接口)作為參數(shù),返回給定Stream的子集直到斷言語(yǔ)句第一次返回 false

          //?語(yǔ)法格式
          default?Stream?takeWhile(Predicate?predicate)
          //代碼示例
          Stream.of(1,2,3).takeWhile(s->?x<2)
          ?????????.forEach(System.out::println);?
          ?//輸出
          ?1

          「dropWhile」

          與 takeWhile()作用相反,使用一個(gè)斷言(Predicate 接口)作為參數(shù),直到斷言語(yǔ)句第一次返回true,返回給定Stream的子集

          //語(yǔ)法
          default?Stream?dropWhile(Predicate?predicate)
          //代碼示例
          Stream.of(1,2,3).dropWhile(s->?x<2)
          ?????????.forEach(System.out::println);
          //輸出
          2
          3

          「iterate」

          iterate() 方法能夠返回以seed(第一個(gè)參數(shù))開(kāi)頭,匹配 Predicate(第二個(gè)參數(shù))直到返回false,并使用第三個(gè)參數(shù)生成下一個(gè)元素的元素流。

          //語(yǔ)法
          static??Stream?iterate(T?seed,?Predicate?hasNext,?UnaryOperator?next)
          //代碼示例
          IntStream.iterate(2,?x?->?x??x*x).forEach(System.out::println);
          //輸出
          2
          4

          「ofNullable」

          如果指定元素為非null,則獲取一個(gè)元素并生成單個(gè)元素流,元素為null則返回一個(gè)空Stream。

          //語(yǔ)法
          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ù)器推送)
          • 進(jìn)程API(控制和管理操作系統(tǒng)進(jìn)程)
          • String底層存儲(chǔ)結(jié)構(gòu)更改(char[]替換為byte[])
          • 標(biāo)識(shí)符添加限制( String _ ="hello"不能用)
          • 響應(yīng)式流 API (支持Java 9中的響應(yīng)式編程)
          ?

          Java 10 新特性

          1.局部變量類(lèi)型推斷

          JDK 10增加了局部變量類(lèi)型推斷(Local-Variable Type Inference)功能,讓 Java 可以像Js里的var一樣可以自動(dòng)推斷數(shù)據(jù)類(lèi)型。Java中的var是一個(gè)保留類(lèi)型名稱,而不是關(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 變量類(lèi)型推斷的使用也有局限性,僅「局限」于以下場(chǎng)景:

          • 具有初始化器的局部變量
          • 增強(qiáng)型for循環(huán)中的索引變量
          • 傳統(tǒng)for循環(huán)中聲明的局部變量

          「不能用于」

          • 推斷方法的參數(shù)類(lèi)型
          • 構(gòu)造函數(shù)參數(shù)類(lèi)型推斷
          • 推斷方法返回類(lèi)型
          • 字段類(lèi)型推斷
          • 捕獲表達(dá)式

          2. 不可變集合的改進(jìn)

          JDK 10中,List,Set,Map 提供了一個(gè)新的靜態(tài)方法copyOf(Collection coll),它返回Collection集合一個(gè)不可修改的副本。

          JDK 源碼:

          static??List?copyOf(Collection?coll)?{
          ????return?ImmutableCollections.listCopy(coll);
          }

          使用實(shí)例:

          var?oldList?=?new?ArrayList();
          oldList.add("歡迎關(guān)注公眾號(hào):");
          oldList.add("撿田螺的小男孩");

          var?copyList?=?List.copyOf(oldList);
          oldList.add("在看、轉(zhuǎn)載、點(diǎn)贊三連");?
          copyList.add("雙擊666");??//UnsupportedOperationException異常

          3. 并行全垃圾回收器 G1

          ?

          JDK 9引入 G1 作為默認(rèn)垃圾收集器,執(zhí)行GC 時(shí)采用的是基于單線程標(biāo)記掃描壓縮算法(mark-sweep-compact)。為了最大限度地減少 Full GC 造成的應(yīng)用停頓的影響,Java 10 中將為 G1 引入多線程并行 GC,同時(shí)會(huì)使用與年輕代回收和混合回收相同的并行工作線程數(shù)量,從而減少了 Full GC 的發(fā)生,以帶來(lái)更好的性能提升、更大的吞吐量。

          ?

          4. 線程本地握手

          Java 10 中線程管控引入JVM安全點(diǎn)的概念,將允許在不運(yùn)行全局JVM安全點(diǎn)的情況下實(shí)現(xiàn)線程回調(diào),由線程本身或者JVM線程來(lái)執(zhí)行,同時(shí)保持線程處于阻塞狀態(tài),這將會(huì)很方便使得停止單個(gè)線程或不停止線程成為可能。

          5. Optional新增orElseThrow()方法

          Optional、OptionalDouble等類(lèi)新增一個(gè)方法orElseThrow(),在沒(méi)有值時(shí)拋出異常

          6. 其他新特性

          • 基于 Java 的 實(shí)驗(yàn)性 JIT 編譯器
          • 類(lèi)數(shù)據(jù)共享
          • Unicode 語(yǔ)言標(biāo)簽擴(kuò)展
          • 根證書(shū)
          • 基于時(shí)間(Time-Based)的版本控制模型

          Java 11 新特性

          1.字符串操作

          String類(lèi)是Java最常用的類(lèi),JDK 11增加了一系列好用的字符串處理方法

          • isBlank() 判空。
          • strip() 去除首尾空格
          • stripLeading() 去除字符串首部空格
          • stripTrailing() 去除字符串尾部空格
          • lines() 分割獲取字符串流。
          • repeat() 復(fù)制字符串
          //?判斷字符串是否為空白
          "??".isBlank();????//?true

          //?去除首尾空格
          "?jay?".strip();??//?"jay"

          //?去除首部空格?
          "?jay?".stripLeading();???//?"jay?"

          去除字符串尾部空格
          "?jay?".stripLeading();???//?"?jay"

          //?行數(shù)統(tǒng)計(jì)
          "a\nb\nc".lines().count();????//?3

          //?復(fù)制字符串
          "jay".repeat(3);???//?"jayjayjay"

          2.用于 Lambda 參數(shù)的局部變量語(yǔ)法

          局部變量類(lèi)型推斷是Java 10引入的新特性,但是不能在Lambda 表達(dá)式中使用。Java 11再次創(chuàng)新,它允許開(kāi)發(fā)者在 Lambda 表達(dá)式中使用 var 進(jìn)行參數(shù)聲明。

          var?map?=?new?HashMap();
          map.put("公眾號(hào)",?"撿田螺的小男孩");
          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對(duì)它更新,Java 11 對(duì)它進(jìn)行標(biāo)準(zhǔn)化。這幾個(gè)版本后,Http Client幾乎被完全重寫(xiě),支持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. 單個(gè)命令編譯運(yùn)行源代碼

          Java 11增強(qiáng)了Java 啟動(dòng)器,使之能夠運(yùn)行單一文件的Java 源代碼。

          • Java 11之前,要運(yùn)行一個(gè) Java 源代碼必須先編譯,再運(yùn)行
          //?編譯
          javac?Jay.java
          //?運(yùn)行
          java?Jay
          • Java 11之后,只要一個(gè)java命令就搞定
          java?Jay.java

          5. ZGC:可伸縮低延遲垃圾收集器

          ZGC ,即 Z Garbage Collector(垃圾收集器或垃圾回收器)。它是一個(gè)可伸縮的、低延遲的垃圾收集器。 ZGC 主要為了滿足如下目標(biāo)進(jìn)行設(shè)計(jì):

          • GC 停頓時(shí)間不超過(guò) 10ms
          • 既能處理幾百 MB 的小堆,也能處理幾個(gè) TB 的大堆
          • 應(yīng)用吞吐能力不會(huì)下降超過(guò) 15%(與 G1 回收算法相比)
          • 方便在此基礎(chǔ)上引入新的 GC 特性和利用 colord
          • 針以及 Load barriers 優(yōu)化奠定基礎(chǔ)
          • 當(dāng)前只支持 Linux/x64 位平臺(tái)

          6.其他一些特性

          • 添加 Epsilon 垃圾收集器。
          • 支持 TLS 1.3 協(xié)議
          • 飛行記錄器分析工具
          • 動(dòng)態(tài)類(lèi)文件常量
          • 低開(kāi)銷(xiāo)的 Heap Profiling

          Java 12 新特性

          1. Switch 表達(dá)式擴(kuò)展(預(yù)覽功能)

          傳統(tǒng)的switch語(yǔ)句,容易漏寫(xiě)break而出錯(cuò),同時(shí)寫(xiě)法并不簡(jiǎn)潔優(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表達(dá)式得到增強(qiáng),能接受語(yǔ)句和表達(dá)式。

          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對(duì)復(fù)雜數(shù)字的格式化

          NumberFormat?numberFormat?=?NumberFormat.getCompactNumberInstance(Locale.CHINA,?NumberFormat.Style.SHORT);
          System.out.println(numberFormat.format(100000));
          //output
          10萬(wàn)

          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 縮進(jìn),每行開(kāi)頭增加空格space和移除空格
          String?result?=?"Java\n?Python\nC".indent(3);
          System.out.println(result);
          //輸出
          ???Java
          ????Python
          ???C

          4. Files.mismatch(Path, Path)

          Java 12 新增了mismatch方法,此方法返回第一個(gè)不匹配的位置,如果沒(méi)有不匹配,則返回 -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 中引入的新的收集器實(shí)用程序,它的作用是 merge 兩個(gè) collector 的結(jié)果,API格式如下:

          public?static?
          ????Collector?teeing(Collector?downstream1,
          ????Collector?downstream2,
          ????BiFunction?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個(gè)新字符、11個(gè)新blocks、7個(gè)新腳本)
          • JVM 常量 API (主要在新的java.lang.invoke.constant包中定義了一系列基于值的符號(hào)引用類(lèi)型,能夠描述每種可加載常量。)
          • Shenandoah GC(低暫停時(shí)間垃圾收集器)
          • G1 收集器提升 (可中止的混合收集集合、及時(shí)返回未使用的已分配內(nèi)存)
          • 默認(rèn)CDS檔案
          • JMH 基準(zhǔn)測(cè)試

          Java 13 新特性

          Switch 表達(dá)式擴(kuò)展(引入 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 語(yǔ)句不再被編譯,而是用 yield 來(lái)進(jìn)行值返回

          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.文本塊升級(jí)

          Java 13之前,字符串不能夠多行使用,需要通過(guò)換行轉(zhuǎn)義或者換行連接符等等,反正就是好麻煩、好難維護(hù)。

          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)部實(shí)現(xiàn)
          • 在 Java 13之前,通過(guò)使用 PlainSocketImpl 作為 SocketImpl 的具體實(shí)現(xiàn)。
          • Java 13 中的新底層實(shí)現(xiàn),引入 NioSocketImpl 的實(shí)現(xiàn)用以替換 SocketImpl 的 PlainSocketImpl 實(shí)現(xiàn),此實(shí)現(xiàn)與 NIO(新 I/O)實(shí)現(xiàn)共享相同的內(nèi)部基礎(chǔ)結(jié)構(gòu),并且與現(xiàn)有的緩沖區(qū)高速緩存機(jī)制集成在一起。

          一個(gè)Socket簡(jiǎn)單例子:

          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();
          ????????}
          ????}
          }

          運(yùn)行以上的實(shí)例,看下是否有以下關(guān)鍵詞輸出~

          [class,load]?sun.nio.ch.NioSocketImpl

          4.FileSystems.newFileSystem新方法

          FileSystems 類(lèi)中添加了以下三種新方法,以便更容易地使用將文件內(nèi)容視為文件系統(tǒng)的文件系統(tǒng)提供程序:

          • 1、newFileSystem(Path)
          • 2、newFileSystem(Path, Map)
          • 3、newFileSystem(Path, Map, ClassLoader)

          5. 增強(qiáng) ZGC 釋放未使用內(nèi)存

          • ZGC 是Java 11 中引入的最為矚目的垃圾回收特性,是一種可伸縮、低延遲的垃圾收集器。但是實(shí)際使用中,它不能夠主動(dòng)將未使用的內(nèi)存釋放給操作系統(tǒng)。
          • Java 13 中對(duì) ZGC 的改進(jìn),包括釋放未使用內(nèi)存給操作系統(tǒng)、支持最大堆大小為 16TB、JVM參數(shù)-XX:SoftMaxHeapSize 來(lái)軟限制堆大小

          6.其他特性

          • 動(dòng)態(tài) CDS 存檔, 擴(kuò)展了 Java 10 中引入的類(lèi)數(shù)據(jù)共享功能, 使用CDS 存檔變得更容易。
          • 文本塊的字符串類(lèi)新方法,如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 對(duì) instanceof 進(jìn)行模式匹配改進(jìn)之后

          if?(person?instanceof?Singer?singer)?{
          ????singer.sing();
          }?else?if?(person?instanceof?Writer?writer)?{
          ???writer.write();
          }

          2.Record 類(lèi)型(預(yù)覽功能)

          Java 14將Record 類(lèi)型作為預(yù)覽特性而引入,有點(diǎn)類(lèi)似于Lombok 的@Data注解,看個(gè)例子吧:

          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 來(lái)聲明一個(gè)類(lèi)時(shí),該類(lèi)將自動(dòng)擁有下面特征:

          • 構(gòu)造方法
          • hashCode() 方法
          • euqals() 方法
          • toString() 方法
          • 類(lèi)對(duì)象被final 關(guān)鍵字修飾,不能被繼承。

          3. Switch 表達(dá)式-標(biāo)準(zhǔn)化

          switch 表達(dá)式在之前的 Java 12 和 Java 13 中都是處于預(yù)覽階段,終于在 Java 14 標(biāo)準(zhǔn)化,成為穩(wěn)定版本。

          • Java 12 為switch 表達(dá)式引入Lambda 語(yǔ)法
          • Java 13 使用yield代替 break 關(guān)鍵字來(lái)返回表達(dá)式的返回值。
          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. 改進(jìn) NullPointerExceptions提示信息

          Java 14 之前:

          String?name?=?song.getSinger().getSingerName()
          ?
          //堆棧信息
          Exception?in?thread?"main"?java.lang.NullPointerException
          ????at?NullPointerExample.main(NullPointerTest.java:6)

          Java 14,通過(guò)引入JVM 參數(shù)-XX:+ShowCodeDetailsInExceptionMessages,可以在空指針異常中獲取更為詳細(xì)的調(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 可識(shí)別內(nèi)存分配
          • 刪除 CMS 垃圾回收器
          • GC 支持 MacOS 和 Windows 系統(tǒng)

          Java 15 新特性

          1.EdDSA 數(shù)字簽名算法

          • 使用 Edwards-Curve 數(shù)字簽名算法(EdDSA)實(shí)現(xiàn)加密簽名。
          • 與其它簽名方案相比,EdDSA 具有更高的安全性和性能。
          • 得到許多其它加密庫(kù)(如 OpenSSL、BoringSSL)的支持。

          2.Sealed Classes(封閉類(lèi),預(yù)覽)

          封閉類(lèi),可以是封閉類(lèi)、封閉接口,防止其他類(lèi)或接口擴(kuò)展或?qū)崿F(xiàn)它們。

          public?abstract?sealed?class?Singer
          ????permits?Jay,?Eason{
          ????...
          }

          類(lèi)Singer被sealed 修飾,是封閉類(lèi),只能被2個(gè)指定子類(lèi)(Jay, Eason)繼承。

          3. Hidden Classes(隱藏類(lèi))

          • 隱藏類(lèi)天生為框架設(shè)計(jì)的。
          • 隱藏類(lèi)只能通過(guò)反射訪問(wèn),不能直接被其他類(lèi)的字節(jié)碼。

          4. Remove the Nashorn JavaScript Engine

          • Nashorn太難維護(hù)了,移除 Nashorn JavaScript引擎成為一種必然
          • 其實(shí)早在JDK 11 中就已經(jīng)被標(biāo)記為 deprecated 了。

          5.Reimplement the Legacy DatagramSocket API(重新實(shí)現(xiàn)DatagramSocket API)

          • 重新實(shí)現(xiàn)老的DatagramSocket API
          • 更改java.net.DatagramSocket 和 java.net.MulticastSocket 為更加簡(jiǎn)單、現(xiàn)代化的底層實(shí)現(xiàn)。

          6.其他

          • Disable and Deprecate Biased Locking(準(zhǔn)備禁用偏向鎖)
          • instanceof 自動(dòng)匹配模式(預(yù)覽)
          • ZGC,一個(gè)可伸縮、低延遲的垃圾回收器。(轉(zhuǎn)正)
          • Text Blocks,文本功能轉(zhuǎn)正(JDK 13和14預(yù)覽,14終于轉(zhuǎn)正)
          • Remove the Solaris and SPARC Ports(刪除 Solaris 和 SPARC 端口)
          • 外部存儲(chǔ)器訪問(wèn) API(允許Java 應(yīng)用程序安全有效地訪問(wèn) Java 堆之外的外部?jī)?nèi)存。)
          • Record類(lèi)型二次預(yù)覽(在Java 14就預(yù)覽過(guò)啦)

          參考與感謝

          • 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 個(gè)新特性,刷新你的認(rèn)知!!



          • Reference
          [1]

          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/

          點(diǎn)個(gè)?在看?
          在看是一種支持
          ↘↘
          瀏覽 35
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰乱伦小说 | 久久精品夜色国产亚洲AV | 三级黄色国产高清电影 | 逼逼视频 | 国产精品激情无码视频小说 |