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

          從原理上搞懂可變參數(shù),就靠它了

          共 3084字,需瀏覽 7分鐘

           ·

          2021-11-04 19:03

          為了讓鐵粉們能白票到阿里云的服務(wù)器,老王當了整整兩天的客服,真正體驗到了什么叫做“為人民群眾謀福利”的不易和辛酸。正在他眼睛紅腫打算要休息之際,小二跑過來問他:“Java 的可變參數(shù)究竟是怎么一回事?”老王一下子又清醒了,他愛 Java,他愛傳道解惑,他愛這群尊敬他的讀者。

          PS:star 這種事,只能求,不求沒效果,鐵子們,《Java 程序員進階之路》在 GitHub 上已經(jīng)收獲了 514 枚星標,鐵子們趕緊去點點了,沖 600 star

          https://github.com/itwanger/toBeBetterJavaer

          可變參數(shù)是 Java 1.5 的時候引入的功能,它允許方法使用任意多個、類型相同(is-a)的值作為參數(shù)。就像下面這樣。

          public?static?void?main(String[]?args)?{
          ????print("沉");
          ????print("沉",?"默");
          ????print("沉",?"默",?"王");
          ????print("沉",?"默",?"王",?"二");
          }

          public?static?void?print(String...?strs)?{
          ????for?(String?s?:?strs)
          ????????System.out.print(s);
          ????System.out.println();
          }

          靜態(tài)方法 print() 就使用了可變參數(shù),所以 print("沉") 可以,print("沉", "默") 也可以,甚至 3 個、 4 個或者更多個字符串都可以作為參數(shù)傳遞給 print() 方法。

          說到可變參數(shù),我想起來阿里巴巴開發(fā)手冊上有這樣一條規(guī)約。

          意思就是盡量不要使用可變參數(shù),如果要用的話,可變參數(shù)必須要在參數(shù)列表的最后一位。既然坑位有限,只能在最后,那么可變參數(shù)就只能有一個(悠著點,悠著點)。如果可變參數(shù)不在最后一位,IDE 就會提示對應(yīng)的錯誤,如下圖所示。

          可變參數(shù)看起來就像是個語法糖,它背后究竟隱藏了什么呢?老王想要一探究竟,它在追求真理這條路上一直很執(zhí)著。

          其實也很簡單。當使用可變參數(shù)的時候,實際上是先創(chuàng)建了一個數(shù)組,該數(shù)組的大小就是可變參數(shù)的個數(shù),然后將參數(shù)放入數(shù)組當中,再將數(shù)組傳遞給被調(diào)用的方法

          這就是為什么可以使用數(shù)組作為參數(shù)來調(diào)用帶有可變參數(shù)的方法的根本原因。代碼如下所示。

          public?static?void?main(String[]?args)?{
          ????print(new?String[]{"沉"});
          ????print(new?String[]{"沉",?"默"});
          ????print(new?String[]{"沉",?"默",?"王"});
          ????print(new?String[]{"沉",?"默",?"王",?"二"});
          }

          public?static?void?print(String...?strs)?{
          ????for?(String?s?:?strs)
          ????????System.out.print(s);
          ????System.out.println();
          }

          那如果方法的參數(shù)是一個數(shù)組,然后像使用可變參數(shù)那樣去調(diào)用方法的時候,能行得通嗎?

          留個思考題,大家也可以去試一試

          那一般什么時候使用可變參數(shù)呢?

          可變參數(shù),可變參數(shù),顧名思義,當一個方法需要處理任意多個相同類型的對象時,就可以定義可變參數(shù)。Java 中有一個很好的例子,就是 String 類的 format() 方法,就像下面這樣。

          System.out.println(String.format("年紀是:?%d",?18));
          System.out.println(String.format("年紀是:?%d?名字是:?%s",?18,?"沉默王二"));

          %d 表示將整數(shù)格式化為 10 進制整數(shù),%s 表示輸出字符串。

          如果不使用可變參數(shù),那需要格式化的參數(shù)就必須使用“+”號操作符拼接起來了。麻煩也就惹上身了。

          在實際的項目代碼中,開源包 slf4j.jar 的日志輸出就經(jīng)常要用到可變參數(shù)(log4j 就沒法使用可變參數(shù),日志中需要記錄多個參數(shù)時就痛苦不堪了)。就像下面這樣。

          protected?Logger?logger?=?LoggerFactory.getLogger(getClass());
          logger.debug("名字是{}",?mem.getName());
          logger.debug("名字是{},年紀是{}",?mem.getName(),?mem.getAge());

          查看源碼就可以發(fā)現(xiàn),debug() 方法使用了可變參數(shù)。

          public?void?debug(String?format,?Object...?arguments);

          那在使用可變參數(shù)的時候有什么注意事項嗎?

          有的。我們要避免重載帶有可變參數(shù)的方法——這樣很容易讓編譯器陷入自我懷疑中。

          public?static?void?main(String[]?args)?{
          ????print(null);
          }

          public?static?void?print(String...?strs)?{
          ????for?(String?a?:?strs)
          ????????System.out.print(a);
          ????System.out.println();
          }

          public?static?void?print(Integer...?ints)?{
          ????for?(Integer?i?:?ints)
          ????????System.out.print(i);
          ????System.out.println();
          }

          這時候,編譯器完全不知道該調(diào)用哪個 print() 方法,print(String... strs) 還是 print(Integer... ints),傻傻分不清。

          假如真的需要重載帶有可變參數(shù)的方法,就必須在調(diào)用方法的時候給出明確的指示,不要讓編譯器去猜。

          public?static?void?main(String[]?args)?{
          ????String?[]?strs?=?null;
          ????print(strs);

          ????Integer?[]?ints?=?null;
          ????print(ints);
          }

          public?static?void?print(String...?strs)?{
          }

          public?static?void?print(Integer...?ints)?{
          }

          上面這段代碼是可以編譯通過的。因為編譯器知道參數(shù)是 String 類型還是 Integer 類型,只不過為了運行時不拋出 NullPointerException,兩個 print() 方法的內(nèi)部要做好判空操作。


          這是《Java 程序員進階之路》專欄的第 65 篇。Java 程序員進階之路,風趣幽默、通俗易懂,對 Java 初學者極度友好和舒適??,內(nèi)容包括但不限于 Java 語法、Java 集合框架、Java IO、Java 并發(fā)編程、Java 虛擬機等核心知識點。

          點擊上方名片,發(fā)送消息「03」 就可以獲取《Java 程序員進階之路》的 PDF 版了,一起成為更好的 Java 工程師。

          瀏覽 37
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  狠狠操 五月天 | 黄色一级大片在线免费看产 | 操比一区二区三区 | 西西444WWW无码视频 | 人人摸人人爱人人操 |