久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      Java 可變參數(shù)

      在 Java 5 中提供了變長參數(shù),允許在調(diào)用方法時(shí)傳入不定長度的參數(shù)。變長參數(shù)是 Java 的一個(gè)語法糖,本質(zhì)上還是基于數(shù)組的實(shí)現(xiàn):

      void foo(String... args);  void foo(String[] args);
      //方法簽名   ([Ljava/lang/String;)V // public void foo(String[] args)

      定義方法

      在定義方法時(shí),在最后一個(gè)形參后加上三點(diǎn) ,就表示該形參可以接受多個(gè)參數(shù)值,多個(gè)參數(shù)值被當(dāng)成數(shù)組傳入。上述定義有幾個(gè)要點(diǎn)需要注意:

      • 可變參數(shù)只能作為函數(shù)的最后一個(gè)參數(shù),但其前面可以有也可以沒有任何其他參數(shù)

      • 由于可變參數(shù)必須是最后一個(gè)參數(shù),所以一個(gè)函數(shù)最多只能有一個(gè)可變參數(shù)

      • Java的可變參數(shù),會(huì)被編譯器轉(zhuǎn)型為一個(gè)數(shù)組

      • 變長參數(shù)在編譯為字節(jié)碼后,在方法簽名中就是以數(shù)組形態(tài)出現(xiàn)的。這兩個(gè)方法的簽名是一致的,不能作為方法的重載。如果同時(shí)出現(xiàn),是不能編譯通過的??勺儏?shù)可以兼容數(shù)組,反之則不成立

        public void foo(String...varargs){}    foo("arg1", "arg2", "arg3");    //上述過程和下面的調(diào)用是等價(jià)的  foo(new String[]{"arg1", "arg2", "arg3"});
      • J2SE 1.5 中新增了“泛型”的機(jī)制,可以在一定條件下把一個(gè)類型參數(shù)化。例如,可以在編寫一個(gè)類的時(shí)候,把一個(gè)方法的形參的類型用一個(gè)標(biāo)識(shí)符(如T)來代表, 至于這個(gè)標(biāo)識(shí)符到底表示什么類型,則在生成這個(gè)類的實(shí)例的時(shí)候再行指定。這一機(jī)制可以用來提供更充分的代碼重用和更嚴(yán)格的編譯時(shí)類型檢查。不過泛型機(jī)制卻不能和個(gè)數(shù)可變的形參配合使用。如果把一個(gè)能和不確定個(gè)實(shí)參相匹配的形參的類型,用一個(gè)標(biāo)識(shí)符來代表,那么編譯器會(huì)給出一個(gè) “generic array creation” 的錯(cuò)誤

        public class Varargs {        public static void test(String... args) {          for(String arg : args) {//當(dāng)作數(shù)組用foreach遍歷              System.out.println(arg);          }      }      //Compile error      //The variable argument type Object of the method must be the last parameter      //public void error1(String... args, Object o) {}      //public void error2(String... args, Integer... i) {}        //Compile error      //Duplicate method test(String...) in type Varargs      //public void test(String[] args){}  }

      可變參數(shù)方法的調(diào)用

      調(diào)用可變參數(shù)方法,可以給出零到任意多個(gè)參數(shù),編譯器會(huì)將可變參數(shù)轉(zhuǎn)化為一個(gè)數(shù)組。也可以直接傳遞一個(gè)數(shù)組,示例如下:

      public class Varargs {        public static void test(String... args) {          for(String arg : args) {              System.out.println(arg);          }      }        public static void main(String[] args) {          test();//0個(gè)參數(shù)          test("a");//1個(gè)參數(shù)          test("a","b");//多個(gè)參數(shù)          test(new String[] {"a", "b", "c"});//直接傳遞數(shù)組      }  }

      方法重載

      優(yōu)先匹配固定參數(shù)

      調(diào)用一個(gè)被重載的方法時(shí),如果此調(diào)用既能夠和固定參數(shù)的重載方法匹配,也能夠與可變長參數(shù)的重載方法匹配,則選擇固定參數(shù)的方法:

      public class Varargs {        public static void test(String... args) {          System.out.println("version 1");      }        public static void test(String arg1, String arg2) {          System.out.println("version 2");      }      public static void main(String[] args) {          test("a","b");//version 2 優(yōu)先匹配固定參數(shù)的重載方法                  test();//version 1      }  }

      >匹配多個(gè)可變參數(shù)

      調(diào)用一個(gè)被重載的方法時(shí),如果此調(diào)用既能夠和兩個(gè)可變長參數(shù)的重載方法匹配,則編譯出錯(cuò):

      public class Varargs {        public static void test(String... args) {          System.out.println("version 1");      }        public static void test(String arg1, String... arg2) {          System.out.println("version 2");      }      public static void main(String[] args) {          test("a","b");//Compile error      }  }

      方法重寫

      避免帶有變長參數(shù)的方法重載

      即便編譯器可以按照優(yōu)先匹配固定參數(shù)的方式確定具體的調(diào)用方法,但在閱讀代碼的依然容易掉入陷阱。要慎重考慮變長參數(shù)的方法重載。

      別讓 null 值和空值威脅到變長方法

      public class Client {         public void methodA(String str,Integer... is){              }           public void methodA(String str,String... strs){                 }           public static void main(String[] args) {               Client client = new Client();               client.methodA("China", 0);               client.methodA("China", "People");               client.methodA("China");  //compile error             client.methodA("China",null);  //compile error       }    }

      修改如下:

      public static void main(String[] args) {         Client client = new Client();         String[] strs = null;         client.methodA("China",strs);    }

      讓編譯器知道這個(gè)null值是String類型的,編譯即可順利通過,也就減少了錯(cuò)誤的發(fā)生。

      覆寫變長方法也要循規(guī)蹈矩

      package com;  public class VarArgsTest2 {      /**       * @param args       */      public static void main(String[] args) {          // TODO Auto-generated method stub          // 向上轉(zhuǎn)型          Base base = new Sub();          base.print("hello");          // 不轉(zhuǎn)型          Sub sub = new Sub();          sub.print("hello");//compile error      }  }  // 基類  class Base {      void print(String... args) {          System.out.println("Base......test");      }  }  // 子類,覆寫父類方法  class Sub extends Base {      @Override      void print(String[] args) {          System.out.println("Sub......test");      }  }

      第一個(gè)能編譯通過,這是為什么呢?事實(shí)上,base 對象把子類對象 sub 做了向上轉(zhuǎn)型,形參列表是由父類決定的,當(dāng)然能通過。而看看子類直接調(diào)用的情況,這時(shí)編譯器看到子類覆寫了父類的 print 方法,因此肯定使用子類重新定義的 print 方法,盡管參數(shù)列表不匹配也不會(huì)跑到父類再去匹配下,因?yàn)檎业搅司筒辉僬伊?,因此有了類型不匹配的錯(cuò)誤。

      這是個(gè)特例,覆寫的方法參數(shù)列表竟然可以與父類不相同,這違背了覆寫的定義,并且會(huì)引發(fā)莫名其妙的錯(cuò)誤。

      這里,總結(jié)下覆寫必須滿足的條件:

      • 覆寫方法不能縮小訪問權(quán)限

      • 參數(shù)列表必須與被覆寫方法相同(包括顯示形式)

      • 返回類型必須與被覆寫方法的相同或是其子類

      • 覆寫方法不能拋出新的異常,或者超出父類范圍的異常,但是可以拋出更少、更有限的異常,或者不拋出異常


      可能出現(xiàn)的問題

      使用 Object… 作為變長參數(shù):

      public void foo(Object... args) {      System.out.println(args.length);  }    foo(new String[]{"arg1", "arg2", "arg3"}); //3  foo(100, new String[]{"arg1", "arg1"}); //2    foo(new Integer[]{1, 2, 3}); //3  foo(100, new Integer[]{1, 2, 3}); //2  foo(1, 2, 3); //3  foo(new int[]{1, 2, 3}); //1

      int[] 無法轉(zhuǎn)型為 Object[], 因而被當(dāng)作一個(gè)單純的數(shù)組對象 ; Integer[] 可以轉(zhuǎn)型為 Object[], 可以作為一個(gè)對象數(shù)組。


      反射方法調(diào)用時(shí)的注意事項(xiàng)

      public class Test {      public static void foo(String... varargs){          System.out.println(args.length);      }        public static void main(String[] args){          String[] varArgs = new String[]{"arg1", "arg2"};          try{              Method method = Test.class.getMethod("foo", String[].class);              method.invoke(null, varArgs);              method.invoke(null, (Object[])varArgs);              method.invoke(null, (Object)varArgs);              method.invoke(null, new Object[]{varArgs});          } catch (Exception e){              e.printStackTrace();          }      }  }

      上面的四個(gè)調(diào)用中,前兩個(gè)都會(huì)在運(yùn)行時(shí)拋出 java.lang.IllegalArgumentException: wrong number of arguments 異常,后兩個(gè)則正常調(diào)用。

      反射是運(yùn)行時(shí)獲取的,在運(yùn)行時(shí)看來,可變長參數(shù)和數(shù)組是一致的,因而方法簽名為:

      //方法簽名  ([Ljava/lang/String;)V // public void foo(String[] varargs)

      再來看一下 Method 對象的方法聲明:

      Object invoke(Object obj, Object... args)

      args 雖然是一個(gè)可變長度的參數(shù),但是 args 的長度是受限于該方法對象代表的真實(shí)方法的參數(shù)列表長度的,而從運(yùn)行時(shí)簽名來看,([Ljava/lang/String;)V 實(shí)際上只有一個(gè)形參,即 String[] varargs,因而 invoke(Object obj, Object… args) 中可變參數(shù) args 的實(shí)參長度只能為1

      //Object invoke(Object obj, Object... args)  //String[] varArgs = new String[]{"arg1", "arg2"};  method.invoke(null, varArgs); //varArgs長度為2,錯(cuò)誤  method.invoke(null, (Object[])varArgs); //將String[]轉(zhuǎn)換為Object[],長度為2的,錯(cuò)誤  method.invoke(null, (Object)varArgs);//將整個(gè)String[] 轉(zhuǎn)為Object,長度為1,符合  method.invoke(null, new Object[]{varArgs});//Object[]長度為1,正確。上一個(gè)和這個(gè)是等價(jià)的

      什么時(shí)候使用可變長參數(shù)?

      Stack Overflow 上有個(gè)關(guān)于變長參數(shù)使用的問題。簡單地說,
      在不確定方法需要處理的對象的數(shù)量時(shí)可以使用可變長參數(shù),會(huì)使得方法調(diào)用更簡單,無需手動(dòng)創(chuàng)建數(shù)組 new T[]{…}

      原文地址:https://blog.csdn.net/qiuchengjia/article/details/52910888

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)