<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>

          這些Java9 超牛的新特性,你竟然還沒用過?

          共 15368字,需瀏覽 31分鐘

           ·

          2021-04-17 01:08

          互聯(lián)網(wǎng)技術(shù)的更新日新月異,而對(duì)于jdk,大部分人平時(shí)都是使用的jdk1.8,然而,如今jdk已經(jīng)更新到了15馬上變16,本篇文章我們就來看看jdk9到底更新了一些什么內(nèi)容。                                                                                                              

          目錄結(jié)構(gòu)變化

          有關(guān)jdk9的下載安裝與環(huán)境配置在這里就不作介紹了,直接來看看它與jdk8的第一個(gè)區(qū)別,目錄結(jié)構(gòu)的變化。

          上圖是jdk8的目錄結(jié)構(gòu),下圖是jdk9的目錄結(jié)構(gòu):

          兩者最明顯的區(qū)別在于jdk9中已經(jīng)不包含jre了,其它內(nèi)容變化倒是不大。

          模塊化

          我們知道,Java編寫的項(xiàng)目是比較臃腫的,編譯運(yùn)行需要耗費(fèi)大量的時(shí)間,為此,java9提供了模塊化,使得開發(fā)者可以指定項(xiàng)目具體需要使用哪些類庫(kù),以排除無關(guān)緊要的jar包,增加項(xiàng)目運(yùn)行效率。

          首先創(chuàng)建一個(gè)Java項(xiàng)目:

          在該項(xiàng)目下創(chuàng)建兩個(gè)模塊,創(chuàng)建方法為 右擊項(xiàng)目-->New-->Module:

          模塊創(chuàng)建完成后,在module-1中編寫一個(gè)Bean:

          package com.wwj.bean;

          public class Person {

              private String name;
              private int age;

              public Person() {
              }

              public Person(String name, int age) {
                  this.name = name;
                  this.age = age;
              }

              public String getName() {
                  return name;
              }

              public void setName(String name) {
                  this.name = name;
              }

              public int getAge() {
                  return age;
              }

              public void setAge(int age) {
                  this.age = age;
              }

              @Override
              public String toString() {
                  return "Person{" +
                          "name='" + name + '\'' +
                          ", age=" + age +
                          '}';
              }
          }

          然后我們?cè)趍odule-2中創(chuàng)建一個(gè)測(cè)試文件:

          會(huì)發(fā)現(xiàn)在module-2中是無法使用module-1中的Person類的,這是因?yàn)閖dk9對(duì)項(xiàng)目進(jìn)行了模塊化,若想要使用到其它模塊的類,需要作如下操作。

          在module-1中創(chuàng)建module-info文件:

          編寫如下內(nèi)容:

          module module1 {
              // 導(dǎo)出包
              exports com.wwj.bean;
          }

          并在module-2中創(chuàng)建module-info文件,編寫如下內(nèi)容:

          module module2 {
              // 引入模塊
              requires module1;
          }

          這樣我們就可以順利地使用到module-1中com.wwj.bean包下的類了:

          再舉個(gè)例子,比如你想打印日志,你就需要使用Logger類,然而:

          此時(shí)Logger類也是報(bào)錯(cuò)的,而且你會(huì)發(fā)現(xiàn)導(dǎo)包是導(dǎo)入不了的,此時(shí)我們就需要在module-info中引入Logger模塊:

          module module2 {
              requires module1;
              requires java.logging;
          }

          這樣就能夠使用Logger類了:

          通過這樣的方式,使得虛擬機(jī)在加載項(xiàng)目時(shí)只會(huì)去加載module-info中配置的模塊,從而大大提升了運(yùn)行效率。 

          jshell命令

          在jdk9之前,我們?nèi)羰窍雸?zhí)行一個(gè)非常簡(jiǎn)單的程序,比如做一個(gè)加法,你需要?jiǎng)?chuàng)建java文件,然后編譯執(zhí)行。

          這顯然非常繁瑣,那它能不能夠像Python那樣有一個(gè)交互式的編程環(huán)境呢?為此,jdk9提供了jshell。

          使用方法非常簡(jiǎn)單,在cmd窗口中輸入jshell:

          在jshell中,我們能夠進(jìn)行輸出、定義變量、計(jì)算等等很多操作,jshell也會(huì)在我們按下回車后立即給予我們反饋:

          創(chuàng)建方法并調(diào)用:

          jshell還提供了一些非常好用的命令,比如/list通過它能夠查看歷史執(zhí)行的命令:

          jshell> /list
             1 : System.out.println("Hello World
             3 : System.out.println("Hello World
             4 : int i = 10;
             5 : int j = 10;
             6 : int result = i + j;
             7 : System.out.println(result);
             8 : public int add(int i,int j){
                 return i + j;
                 }
             9 : System.out.println(add(i,j));

          /imports,查看導(dǎo)入的包:

          jshell> /imports
          |    import java.io.*
          |    import java.math.*
          |    import java.net.*
          |    import java.nio.file.*
          |    import java.util.*
          |    import java.util.concurrent.*
          |    import java.util.function.*
          |    import java.util.prefs.*
          |    import java.util.regex.*
          |    import java.util.stream.*

          /vars,查看定義的變量:

          jshell> /vars
          |    int i = 10
          |    int j = 10
          |    int result = 20

          /methods查看定義的方法:

          jshell> /methods
          |    int add(int,int)

          /edit,彈出對(duì)話框用于修改代碼:


          前言多版本兼容Jar包

          當(dāng)一個(gè)新版本的jdk出現(xiàn)時(shí),開發(fā)者并不愿意立馬將其開發(fā)環(huán)境切換到新的版本,因?yàn)樗暮芏囗?xiàng)目還是用之前的jdk進(jìn)行開發(fā)的,當(dāng)切換了新版本的jdk后,很可能會(huì)因?yàn)槠洳患嫒菀恍├系膉ar包從而導(dǎo)致項(xiàng)目出錯(cuò)。

          jdk9考慮到了這一點(diǎn),其多版本兼容jar包的功能可以使開發(fā)者創(chuàng)建僅在特定版本的java環(huán)境中運(yùn)行庫(kù)程序選擇使用的版本。

          現(xiàn)在有這樣一個(gè)項(xiàng)目,其中有兩個(gè)包,一個(gè)java包,一個(gè)java-9包。

          java包中有兩個(gè)類,分別是:

          public class Generator {

              public Set<String> createStrings() {
                  Set<String> strings = new HashSet<String>();
                  strings.add("Java");
                  strings.add("8");
                  return strings;
              }
          }
          public class Application {

             public static void testMultiJar(){
                Generator gen = new Generator();
                System.out.println("Generated strings: " + gen.createStrings());
             }

          }

          而java-9中的類為:

          public class Generator {
                  
              public Set<String> createStrings() {
                  return Set.of("Java""9");
              }
          }

          現(xiàn)在我們將對(duì)這個(gè)項(xiàng)目進(jìn)行打包,得到一個(gè).jar文件——multijar.jar。

          下面就來測(cè)試一下,新建一個(gè)Java8的項(xiàng)目,并編寫測(cè)試代碼:

          public class MultiJar {

              public static void main(String[] args) {
                  Application.testMultiJar();
              }
          }

          記得將剛才的jar包導(dǎo)入到項(xiàng)目中,運(yùn)行結(jié)果為:

          Generated strings: [Java, 8]

          我們?cè)賹⑦@段代碼放到Java9環(huán)境的項(xiàng)目中運(yùn)行一下,得到結(jié)果:

          Generated strings: [9, Java]

          可以看到,同一段代碼在不同環(huán)境下會(huì)有對(duì)應(yīng)的不同表示,這就是多版本兼容的jar包。

          接口可以定義私有方法了

          從jdk9開始,接口可以定義私有方法了,具體的話也沒有什么好說的,直接看代碼:

          public interface InterfaceTest {

              //jdk7中只能聲明全局常量(使用public static final修飾)和抽象方法(使用public abstract修飾)
              int num = 10;
              void add(int i,int j);
              //jdk8中還能夠聲明靜態(tài)方法和默認(rèn)方法
              static void staticMethod(){

              }

              default void defaultMethod(){

              }
              //jdk9中能夠定義私有方法
              private void privateMethod(){

              }
          }

           

          集合中的泛型

          在jdk8以前,我們?nèi)粝攵x一個(gè)帶有泛型的集合,必須這樣編寫:

          Set<String> set = new HashSet<String>();

          而在jdk8中,我們可以省略后面的泛型,因?yàn)樗梢赃M(jìn)行類型的自動(dòng)推斷:

          Set<String> set = new HashSet<>();

          在jdk9中,我們還能夠?qū)线M(jìn)行如下編寫:

          Set<String> set = new HashSet<>(){};

          這行代碼的意思是創(chuàng)建一個(gè)繼承于HashSet的匿名子類對(duì)象,它將與Set共同使用泛型,那么這樣有什么好處呢?

          好處在于當(dāng)你需要改造Set中的某個(gè)方法時(shí),能夠很方便地實(shí)現(xiàn),比如:

          public static void main(String[] args) {
              Set<String> set = new HashSet<>(){
                  @Override
                  public boolean add(String s) {
                      return super.add(s + "--");
                  }
              };
              set.add("zhangsan");
              set.add("lisi");
              set.add("wangwu");
              for (String str : set) {
                  System.out.println(str);
              }
          }

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

          wangwu--
          zhangsan--
          lisi--


          異常處理

          對(duì)于IO流的異常處理一直為人所詬病,傳統(tǒng)的異常處理過程如下:

          FileInputStream in = null;
          try {
              in = new FileInputStream("");
          catch (FileNotFoundException e) {
              e.printStackTrace();
          }finally {
              if(in != null){
                  try {
                      in.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }

          可以看到代碼非常的臃腫,在jdk8中,我們還有另外一套解決方案:

          try (FileInputStream in = new FileInputStream("")) {
              in.close();
          catch (IOException e) {
              e.printStackTrace();
          }

          將資源放在try語句的括號(hào)內(nèi),我們就不需要手動(dòng)去關(guān)閉流資源了。

          而在jdk9中,我們可以在try()中調(diào)用已經(jīng)實(shí)例化的資源對(duì)象:

          InputStreamReader reader = new InputStreamReader(System.in);
          try (reader) {
              reader.read();
          catch (IOException e) {
              e.printStackTrace();
          }

          這種方式在jdk9之前是不支持的。

          下劃線的使用限制

          在jdk8中,下劃線是可以單獨(dú)作為變量名進(jìn)行定義的:

          int _ = 100;

          而jdk9中禁止了這種變量的定義:


          前言String存儲(chǔ)結(jié)構(gòu)的變化

          在jdk8中,字符串的底層采用的是char數(shù)組:

          而在jdk9中,它不再使用char數(shù)組實(shí)現(xiàn),取而代之的是byte數(shù)組:

          因?yàn)樵赨TF-16編碼中,一個(gè)字符會(huì)占用兩個(gè)字節(jié),而大部分情況下,開發(fā)者使用的String中包含了較多的字母和數(shù)字,它們均只用一個(gè)字節(jié)就能夠存儲(chǔ),所以采用char數(shù)組存儲(chǔ)字符串會(huì)造成大量資源的浪費(fèi),為此,jdk9中特別設(shè)計(jì)了String的實(shí)現(xiàn),將其底層改為了byte數(shù)組。

          只讀集合

          jdk8中提供了unmodifiableList()方法來將一個(gè)集合轉(zhuǎn)變?yōu)橹蛔x集合:

          public static void main(String[] args) {
              List<String> list = new ArrayList<>();
              list.add("a");
              list.add("b");
              list.add("c");
              List<String> readList = Collections.unmodifiableList(list);
              // 只讀集合不允許添加元素
              // readList.add("d");
              readList.forEach(System.out::println);
          }

          若是想創(chuàng)建只讀的Set集合,只需修改方法名即可:

          public static void main(String[] args) {
              Set<Integer> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(12345)));
              set.forEach(System.out::println);
          }

          只讀的map集合也是如此:

          public static void main(String[] args) {
              Map<Object, Object> map = Collections.unmodifiableMap(new HashMap<>() {
                  {
                      put("zhangsan"20);
                      put("lisi"21);
                      put("wangwu"22);
                  }
              });
              map.forEach((k,v) -> System.out.println(k + ":" + v));
          }

          注意這里使用到了jdk9中的另一新特性來初始化Map集合,這在集合中的泛型已經(jīng)介紹過了。

          以上均是jdk8中創(chuàng)建只讀集合的方式,在jdk9中,它的創(chuàng)建方式只會(huì)更加簡(jiǎn)單:

          public static void main(String[] args) {
              List<Integer> list = List.of(12345);
              list.forEach(System.out::println);
          }

          通過of()方法創(chuàng)建的集合它就是一個(gè)只讀集合,是不可以再對(duì)其進(jìn)行修改的。

          然后是Set集合和Map集合:

          public static void main(String[] args) {
              //創(chuàng)建只讀Set
              Set<Integer> set = Set.of(1234);
              //創(chuàng)建只讀Map
              Map<String, Integer> map = Map.of("zhangsan"20"lisi"21"wangwu"22);

              //創(chuàng)建只讀Map的第二種方式
              Map<String, Integer> map = Map.ofEntries(Map.entry("zhangsan"20), Map.entry("lisi"21));
          }


          Stream的增強(qiáng)

          首先是takeWhile方法:

          public static void main(String[] args) {
              // takeWhile
              List<Integer> list = Arrays.asList(1,3,2,5,4);
              Stream<Integer> stream = list.stream();
              Stream<Integer> newStream = stream.takeWhile(x -> x < 3);
              newStream.forEach(System.out::println);
          }

          在該場(chǎng)景中,takeWhile方法的作用是從集合第一個(gè)元素開始查找小于3的元素,第一個(gè)元素1小于3;第二個(gè)元素3不小于3,此時(shí)后面的所有元素都會(huì)被舍棄,所以運(yùn)行結(jié)果為:

          1

          其次是dropWhile方法:

          public static void main(String[] args) {
              // dropWhile
              List<Integer> list = Arrays.asList(1,3,2,5,4);
              Stream<Integer> stream = list.stream();
              Stream<Integer> newStream = stream.dropWhile(x -> x < 3);
              newStream.forEach(System.out::println);
          }

          在該場(chǎng)景中,dropWhile方法的作用是從集合第一個(gè)元素開始查找小于3的元素,第一個(gè)元素1小于3,會(huì)被舍棄;第二個(gè)元素3不小于3,此時(shí)后面的所有元素都被保留,所以運(yùn)行結(jié)果為:

          3
          2
          5
          4

          最后是ofNullable方法,它允許Stream中存放單個(gè)null值:

          public static void main(String[] args) {
              //ofNullable
              Stream<Object> stream = Stream.ofNullable(null);
              System.out.println(stream.count());
          }

          這樣是沒有任何錯(cuò)誤的,運(yùn)行結(jié)果為:

          0

           

          HttpClient

          jdk9中提供了HttpClient來實(shí)現(xiàn)網(wǎng)絡(luò)連接,用法如下:

          public static void main(String[] args) throws IOException, InterruptedException {
              HttpClient client = HttpClient.newHttpClient();
              HttpRequest request = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).GET().build();
              HttpResponse<String> response = client.send(request, HttpResponse.BodyHandler.asString());
              System.out.println(response.statusCode());
              System.out.println(response.version().name());
              System.out.println(response.body());
          }

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

          200
          HTTP_1_1
          <!DOCTYPE html><!--STATUS OK-->
          <html>
          <head>
           <meta http-equiv="content-type" content="text/html;charset=utf-8">
          ......


          前言Java編譯工具的升級(jí)

          jdk9中升級(jí)了java的編譯工具,它提供了sjavac指令用于在多核處理器情況下提升jdk的編譯速度。

          瀏覽 75
          點(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>
                  免费精品久久久久久中文字幕-无删减 | AA片在线观看视频 | 日本熟妇在线播放 | 豆花视频无码在线 | 99久久免费在线视频 |