天天看點

JAVA開發中通用的方法和準則(一)

建議1 不要在常量和變量中出現易混淆的字母

首先,包名要全部小寫,類名要首字母全部大寫(CamelCase),變量名字要采用駝峰命名法命名等等,但是在變量聲明中要注意不要引入容易混淆的字母,嘗試閱讀如下代碼,思考一下列印出的變量i等于多少:

public static void main(String[] args) {
        long i = 1l;
        System.out.println("i的兩倍是:" + (i + i));
    }
           

這麼簡單的例子肯定不會出錯,運作結果22,拷貝運作一下,結果是2.

指派給變量i的值就是數字1,後面是加了一個長整型變量标示字母"l"而已,當你試圖通過閱讀代碼來了解作者的思想時,此情此景就可能會出現,是以為了讓您的程式更容易了解,字母"l"(還有大寫字母O)盡量不要和數字混用,以免閱讀者了解與程式意圖産生偏差,如果混用,字母"l"務必大寫,字母"O"則增加注釋.

注意: 字母"l"作為長整型标示時務必大寫

建議2 莫讓常量蛻變為變量

有人說常量是不可能蛻變為變量的,用了final和static怎麼可能會變,看看一下代碼:

public static void main(String[] args) {
        long i = 1l;
        System.out.println("常量會變的:" + Const.RAND_CONST);
    }
    /*接口常量*/
    interface Const{
        public static final int RAND_CONST = new Random().nextInt();
    }
           

RAND_CONST是常量麼,值會變麼,絕對會變,這種常量的定義方式是非常不可取的,常量在編譯期就必須确定其值,不應該在運作期改變他的值

注意: 務必讓常量的值在運作期保持不變

建議3 三元操作符的類型務必一緻

三元操作符是if-else的簡化寫法,在項目中使用它的地方很多,也很好用,但是好用又簡單的東西并不是刻意随便用,看看下面一段代碼:

public static void main(String[] args) {
        int i = 80;
        String s = String.valueOf(i < 100 ? 90 : 100);
        String s1 = String.valueOf(i < 100 ? 90 : 100.0);
        System.out.println("兩者是否相等 : " + s.equals(s1));
   	}
           

先來分析一下,i的值是80,肯定是小于100的,兩個表達式的傳回值肯定都是90的,轉換成String類型的值也是相等的,但是在s變量中的三元操作符的第二個操作數是100,而s1的第二個操作數是100.0,會不會有影響,運作一下,結果是:“兩者是否相等 : false”.

問題就是出在100和100.0這兩個數上,在變量s中,三元操作符中的第一個操作數和第二個操作數都是int類型,類型想同,傳回的也就是int類型的90,在轉換成Striing,而變量s1卻不是,第一個操作數90(int類型),第二個操作數是100.0(浮點數),兩個操作數類型不一緻,但是三元操作符還必須要傳回一個類型的資料,也不可能為真時傳回int類型,為假時傳回float類型,這時他就會進行類型轉換,int類型就會轉換為浮點數的90.0,傳回的也就是浮點型的90.0,是以與整形的90不相等,下面是三元操作符類型轉換規則:

1). 若兩個操作數不可轉換,則不做轉換,傳回Object類型.

2).若兩個操作數是明确類型的表達式(例如變量),則按照正常的二進制數字來轉 換,int類型轉換為long類型,long類型轉換為float類型等.

3).若兩個操作數中有一個是數字S,另外一個是表達式,且其類型标示為T,那麼若是數字S在T的範圍内,則會轉換為T類型,若S超出了T類型的範圍,則T轉換為S類型(可以參考"建議22",暫未更新).

4)若兩個操作數都是直接量數字,則傳回值類型為範圍較大者.

知道原因了,也就有了相應的解決辦法:保證三元操作符中的兩個操作數類型一緻,即可減少可能錯誤的發生

建議4 避免帶有變長參數的方法重載

在項目或系統的開發中,需要提高代碼的複用性和靈活度,這樣就會導緻我們經常傳遞一些不确定的參數數量到方法中,在Java5之前常用的設計方法就是把形參聲明為一個Collection或者其子類型(List)又或者是數組類型,這種方式的缺點就是需要對null值進行判斷以及長度為0的Collection或數組進行判斷,而Java5以後引入邊長參數就是為了更好地提高方法的複用性,但是變長參數的使用也有一定的規則,變長參數必須是參數清單的最後一個參數,一個參數清單也不能定義多個變長參數.看看一下代碼:

public static void main(String[] args) {
        BasicStandardApplication basicStandardApplication = new BasicStandardApplication();
        basicStandardApplication.calPrice(49900,75);
    }
    /*簡單的折扣計算*/
    public void calPrice(int price, int disCount){
        float knockdownPrice = price * disCount / 100.0F;
        System.out.println("簡單折扣後的價格是:" + formateCurrency(knockdownPrice));
    }
    /*複雜多折扣計算*/
    public void calPrice(int price, int... disCounts){
        float knockdownPrice = price;
        for (int disCount: disCounts) {
            knockdownPrice = knockdownPrice * disCount / 100;
            System.out.println("多折扣計算後的價格:" + formateCurrency(knockdownPrice));
        }
    }
    private String formateCurrency(float knockdownPrice) {
        return NumberFormat.getCurrencyInstance().format(knockdownPrice/100);
    }
           

這是一個計算商品折扣的簡單例子,帶有兩個參數的calPrice方法進行了重載,其中帶有變長參數的calPrice則是計算多折扣的計算方式,也就是類似于生活中的折上折.

仔細看看這兩個重載的方法,有一點小特殊,帶有變長參數的方法範疇覆寫了單個calPrice(int price, int disCount)方法,那麼對于calPrice(49900,75)這種類型的調用,到底該調用那個方法呢,如果傳遞的參數是這個calPrice(49900,75,95)毫無疑問,會調用calPrice(int price, int… disCounts),隻有這一個是符合參數類型的,但是現在75即可以編譯為int類型的75,也可以編譯成數組類型的{75}

運作一下結果:

簡單折扣後的價格是:¥374.25

看來調用的是第一個方法,編譯器首先會會确認方法是否符合方法簽名條件,但是為什麼會選擇第一個不是第二個,因為int類型是是原生資料類型,而數組确實一個對象類型,java編譯器偷懶,會從簡單的開始"猜想",隻要符合條件就會編譯通過,是以就出現了現在這個問題.

是以為了我們的代碼能被看懂,還是慎重使用變長參數的方法重載吧

後續繼續更新

下一篇: #大資料