java代碼編寫出現的陷阱-1:警戒變長參數

在Java5 中提供了變長參數(varargs),也就是在方法定義中可使用個數不肯定的參數,對於同一方法可使用不一樣個數的參數調用,調用的時候能夠給出任意多個參數也可不給參數.java

method(Object...objs){...} .  調用時的代碼是:method("str") 或者method(null),method("張三","李四","王五").數組

可是若是出現下面的狀況,可就麻煩了,很少說,看代碼:ide

  1. public class Client {     spa

  2.     //簡單折扣計算  orm

  3.     public void calPrice(int price,int discount){  xml

  4.           float knockdownPrice =price * discount / 100.0F;  對象

  5.           System.out.println("折扣後的價格:"+formateCurrency(knockdownPrice));  ci

  6.     }    get

  7.     //複雜多折扣計算(出如今折上折需求上)編譯器

  8.    public void calPrice(int price,int... discounts){  

  9.           float knockdownPrice = price;  

  10.           for(int discount:discounts){  

  11.                knockdownPrice = knockdownPrice * discount / 100;  

  12.           }  

  13.             System.out.println("折上折後的價格:"+formateCurrency(knockdownPrice));

  14.    }  

  15.     //格式化成本的貨幣形式  

  16.     private String formateCurrency(float price){  

  17.            return NumberFormat.getCurrencyInstance().format(price/100);  

  18.     }  

  19.     public static void main(String[] args) {  

  20.           Client client = new Client();  

  21.           //499元的貨物,打75折

  22.           client.calPrice(49900, 75);  

  23.     }  

   程序調用了最終調用了非變長參數的方法,由於java在編譯時,首先會根據實參的數量和類型來進行處理,並且肯定是否符合方法簽名條件,而兩個重載方法中,int類型的是一個原生數據類型,而多變參數其實是一個數組對象,編譯器偷懶,因而先從簡單的方法簽名開始,若是符合條件,便可編譯經過,因而就出現了這種狀況。

下面變長參數方法還有一種狀況挺煩人的,看代碼:

  1. public class Client {

  2.     public void methodA(String...strs){ }

  3.     public void methodA(Integer...ints){ }

  4.     public static void main(String[] args) {  

  5.           Client client = new Client();  

  6.           //調用方法

  7.           client.methodA(null);    //編譯出錯

  8.     }  

爲何會編譯編譯出錯了,兩個方法重載是沒問題的,可是在調用時,傳入的參數直接使用實參數值,這樣java編譯器沒法判斷null屬於何種數據對象.不單單調用者須要"猜想"該調用哪一個方法,並且被調用者也可能產生內部邏輯混亂的狀況.

這個問題的解決方案有兩種:

<1> 調用methodA方法時,設置null一個類型,將變量做爲參數傳入.

<2> methodA方法不重載,將其中的一個方法名改掉.

相關文章
相關標籤/搜索