Java不定長引數
Java不定長引數
轉載:https://www.msyy233.com/posts/33024.html#more
一、不定長引數的基本使用
定義實參個數可變的方法:只要在一個形參的型別與引數名之間加上三個連續的 “.”(即 “…”、英文裡的句中省略號)、就可以讓它和不確定個實參相匹配。
public class Main {
/** 不定長引數方法 */
static int sumvarargs(int... intArrays) {
int sum = 0;
for (int i = 0; i < intArrays.length; i++) {
sum += intArrays[i];
}
return sum;
}
public static void main(String args[]) {
// 呼叫方式一
int sum1 = sumvarargs(10, 12, 13);
// 呼叫方式二
int[] varargs = new int[]{10, 12, 13};
int sum2 = sumvarargs(varargs);
// 輸出結果 => sum1:35
System.out.printf("sum1:%d%n", sum1);
// 輸出結果 => sum2:35
System.out.printf("sum2:%d%n", sum2);
}
}
工作原理:
- 以呼叫方傳遞的引數的數目為長度建立一個陣列、
- 將實參的值放入陣列中、
- 將陣列的引用傳遞給被調方法、
Java原始碼使用例子:String.format(String format, Object... args)
二、不定長引數問題和規範
1、呼叫問題和規範
-
如果呼叫的方法可以和兩個可變引數匹配、則編譯報錯
public class Main { static int sumvarargs(int... intArrays) { int sum = 0; for (int i = 0; i < intArrays.length; i++) { sum += intArrays[i]; } return sum; } static int sumvarargs(int intArray, int... intArrays) { int sum = intArray; for (int i = 0; i < intArrays.length; i++) { sum += intArrays[i]; } return sum; } public static void main(String args[]) { /* 下面兩個呼叫都不能編譯通過、 因為編譯器不知道該選哪個方法呼叫 */ int sum1 = sumvarargs(10); int sum2 = sumvarargs(10, 12, 13); System.out.printf("sum:%d%n", sum1); System.out.printf("sum:%d%n", sum2); } }
如果呼叫可變長引數的過載方法時隱藏了實參型別、也可能發生類似問題一中錯誤、
public class Main {
static int sumvarargs(String desc, int... intArrays) {
System.out.println(desc);
int sum = 0;
if (intArrays == null)
return sum;
for (int i = 0; i < intArrays.length; i++) {
sum += intArrays[i];
}
return sum;
}
static int sumvarargs(String desc, String... strArrays) {
System.out.println(desc);
int sum = 0;
if (strArrays == null)
return sum;
for (int i = 0; i < strArrays.length; i++) {
int intArray = Integer.valueOf(strArrays[i]);
sum += intArray;
}
return sum;
}
public static void main(String args[]) {
/*
下面兩個呼叫都不能編譯通過、
因為編譯器不知道該選哪個方法呼叫
*/
int sum1 = sumvarargs("sum");
int sum2 = sumvarargs("sum", null);
System.out.printf("sum1:%d%n", sum1);
System.out.printf("sum2:%d%n", sum2);
}
}
上面的情況是由於不是很好的編碼習慣造成的、即呼叫者隱藏了實參型別、
避免這種情況的程式碼寫法如下:
public class Main {
static int sumvarargs(String desc, int... intArrays) {
System.out.println(desc);
int sum = 0;
if (intArrays == null)
return sum;
for (int i = 0; i < intArrays.length; i++) {
sum += intArrays[i];
}
return sum;
}
static int sumvarargs(String desc, String... strArrays) {
System.out.println(desc);
int sum = 0;
if (strArrays == null)
return sum;
for (int i = 0; i < strArrays.length; i++) {
int intArray = Integer.valueOf(strArrays[i]);
sum += intArray;
}
return sum;
}
/*
* 控制檯輸出:
* 呼叫int不定長方法
* 呼叫str不定長方法
* sum1:0
* sum2:3
*/
public static void main(String args[]) {
int[] intArrays = null;
int sum1 = sumvarargs("呼叫int不定長方法", intArrays);
int sum2 = sumvarargs("呼叫str不定長方法", new String[]{"1", "2"});
System.out.printf("sum1:%d%n", sum1);
System.out.printf("sum2:%d%n", sum2);
}
}
呼叫的方法能夠和固定引數的方法匹配、也能夠與可變長引數的方法匹配、則選擇固定引數的方法
public class Main {
static int sumvarargs(int intArray) {
return intArray * 2;
}
static int sumvarargs(int... intArrays) {
int sum = 0;
for (int i = 0; i < intArrays.length; i++) {
sum += intArrays[i];
}
return sum;
}
public static void main(String args[]) {
int sum1 = sumvarargs(10);
int sum2 = sumvarargs(10, 12, 13);
// 輸出結果 => sum1:20
System.out.printf("sum1:%d%n", sum1);
// 輸出結果 => sum2:35
System.out.printf("sum2:%d%n", sum2);
}
}
2、定義問題和規範
-
一個方法只能有一個可變長引數、並且這個可變長引數必須是該方法的最後一個引數
public class Main { /** 編譯報錯 */ static void test(String... strs, List list) {} /** 編譯報錯 */ static void test(String... strs, List... lists) {} }
重寫變長方法也要循規蹈矩
public class Main { public static void main(String[] args) { // 向上轉型 Base base = new Sub(); base.print("hello"); // 不轉型 Sub sub = new Sub(); sub.print("hello"); // 此行編譯不通過 } } // 基類 class Base { void print(String... args) { System.out.println("Base - args[0]:" + args[0]); } } // 子類,覆寫父類方法 class Sub extends Base { @Override void print(String[] args) { System.out.println("Sub - args[0]:" + args[0]); } }
第一個能編譯通過、這是為什麼呢?事實上、Base物件把子類物件Sub做了向上轉型、形參列表是由父類決定的、當然能通過、而看看子類直接呼叫的情況、這時編譯器看到子類覆寫了父類的print方法、因此肯定使用子類重新定義的print方法、儘管引數列表不匹配也不會跑到父類再去匹配下、因為找到了就不再找了、因此有了型別不匹配的錯誤。
總結下覆寫必須滿足的條件:
-
重寫方法不能縮小訪問許可權
引數列表必須與被重寫方法相同(包括顯示形式)
返回型別必須與被重寫方法的相同或是其子類
重寫方法不能丟擲新的異常、或者超過了父類範圍的異常、但是可以丟擲更少、更有限的異常、或者不丟擲異常
相關文章
- python不定長引數如何呼叫函式?Python函式
- Ruby方法傳不定引數
- C技巧:結構體引數轉成不定引數結構體
- Python怎麼傳遞不定引數Python
- Java的方法可變長引數Java
- Java(三)引數Java
- 讀取不定長字串輸入字串
- 學習javaScript必知必會(1)~js介紹、函式、匿名函式、自呼叫函式、不定長引數JavaScriptJS函式
- Java對比有引數和無引數Java
- 【高等數學】不定積分
- 【Java】可變引數Java
- python函式變長引數Python函式
- APM Java agent 引數配置Java
- [思] 當需要傳遞多個不定引數時,該如何設計 JavaScript 函式?JavaScript函式
- Java方法04:命令列傳遞引數、可變引數Java命令列
- Java方法05:可變引數Java
- Java - 可變引數的使用Java
- 【重學Java】可變引數Java
- Java™ 教程(有界型別引數)Java型別
- python不定長函式:*args 和 **args的使用Python函式
- c#基礎-5.變長引數和引數預設值C#
- java 啟動命令 java -jar 如何追加引數JavaJAR
- Go 快速入門指南 - 變長引數Go
- CSS 實現文字"不定行數"截斷CSS
- PHP 不定個數 de 陣列取交集PHP陣列
- JAVA基礎之-引數傳遞Java
- 教你認識Java 可變引數Java
- 在Java程式中列印java執行時引數Java
- shell 怎麼獲取引數的長度
- GO語言————6.3 傳遞變長引數Go
- golang 防SQL隱碼攻擊 基於反射、TAG標記實現的不定引數檢查器GolangSQL反射
- 從不定方程的非負整數解個數談起
- Java設定JSON字串引數編碼JavaJSON字串
- Java 的可變引數與 Collections 類Java
- java傳送get請求帶引數Java
- 利用Java處理Jmeter介面常用引數JavaJMeter
- Java 獲取系統各項引數Java
- java 傳遞引數的兩種方式Java