改善java程式的151個建議--筆記一,java151--筆記

來源:互聯網
上載者:User

改善java程式的151個建議--筆記一,java151--筆記

一、Java開發中通用的方法和準則

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

eg:long i=1l,這是11還是lL呢,建議使用大寫的方式;

2、不要讓常量變成變數

eg:public static final int RAND_CONST=new Random().nextInt();

3、三元符的類型務必一致

eg:String s=String.valueOf(i<100?90:100.0);

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

eg:calPrice(int price,int discount);

   calPrice(int price,int... discounts);

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

eg:methodA(String str,Integer... is);

methodA(String str,String... strs);

Test:methodA(“China”);

    methodA(“China”,null);

6、覆寫變長方法也要循規蹈矩

Eg:parent:method(int price,int... discounts);

   Children:method(int price,int[] discounts);

7、警惕自增陷阱

Eg:int count=0;for(int i=0;i<10;i++){count=count++};輸出結果為0

8、不要讓就文法困擾

Eg:goto語句、methodA:methodB();

9、少用靜態匯入

10、不要在本類中覆蓋靜態匯入的變數和方法

11、養成良好的習慣,顯式聲明UID

Eg:序列化

12、避免用序列化類別在建構函式中為不變數(final修飾)賦值

13、避免為final變數複雜賦值

Eg:public final String name=initName();

Public String initName(){return “hello”;}

還原序列化時final變數在以下情況下不會被重新賦值:

1)通過建構函式為final變數賦值;

2)通過方法返回值為final變數賦值;

3)Final修飾的屬性不是基本類型;

14、使用序列化類別的私人方法巧妙解決部分屬性持久化問題

15、Break萬萬不可忘

Switch....case中....

16、易變業務使用指令碼語言編寫

例如通過java中的ScriptEngine調用javascript中的方法

17、慎用動態編譯:在運行期間直接編譯.java檔案,執行.class,將java類資訊寫入到字串中,然後運行期間調用相關介面執行字串中的java資訊

18、避免instanceOf非預期結果,注意instanceOf成立的條件是運算元左右兩邊要有繼承或者實現關係,否則編譯會報錯

Eg:’A’ instanceOf Character、new Date() instanceOf String,

19、斷言絕對不是雞肋:assert<布林運算式>:<錯誤資訊>

20、不要只替換一個類:發布應用系統時禁止使用類檔案替換方式,整體war包發布才是完全之策

二、基本類型

21、判斷奇偶數,用偶判斷,不用奇判斷

Eg:i%2==1?”奇數”:”偶數”;-1的時候會出現問題

正確使用:i%2==0?”偶數”:”奇數”;

22、用BigDecimal和整形類型處理貨幣

23、不要讓類型默默轉換

Eg:public static final int LENGTH_SPEED=30*10000*1000;

   long v=LENGTH_SPEED*60*8會出現負數,因為計算的時候,先是運算再進行類型轉換的,三個數都是int類型,計算後超出int的最大值,所以計算結果為負值;

正確的方式:long v=1L*LENGTH_SPEED*60*8;計算的時候後面的都會轉換成為長整形

24、整形類型的邊界值需要考慮,在進行單元測試的時候,進行int型別參數測試的時候,需要考慮下面幾個值:0、正最大、負最小

25、不要讓四捨五入虧了一方,例如在做銀行、金融相關行業的系統的時候,要根據不同的情境,謹慎選擇不同的舍入模式,以提高項目的精準度,減少演算法損失

26、提防封裝類型的null值:封裝類型參與運算時候,要做null值校正

27、謹慎封裝類型的大小比較

Eg:Integer a=new Integer(100);

   Integer b=new Integer(100);

   a==b:false,a>b:false,a<b:false;

28、優先使用整形池:基本類型的裝箱動作是通過valueOf方法來實現的,對於int類型轉換為Integer對象,如果int值的範圍在-128到127之間,那麼它直接從cache數組中獲得,不在該範圍的int類型則通過new產生封裝對象,通過封裝類的valueOf產生封裝執行個體可以顯著提高空間和時間效能

29、優先選擇基本類型

Eg:int i=0;

test(i);

test(Integer.valueOf(i));

public static void test(long i){}

public static void test(Long i){}

在進行自動裝箱的過程中,基本類型可以先加寬,再轉變成寬類型的封裝類型,但是不能直接轉變成寬類型的封裝類型。Int可以加寬變成long類型,然後再轉變成為Long對象,但是不能直接變成Long對象。

30、不要隨便設定隨機數的種子

Eg:Random random=new Random(1000);產生隨機數的種子被固定了

Java中產生隨機數:Random、Math.random();

三、類對象及方法

31、在介面中不要存在實現的代碼

Interface S{public void doSomething();} interface B{S s=new S(){public void dos{}}}

32、靜態變數一定要先聲明後賦值

Eg:static{i=100;} public static int i=1;

33、不要覆寫靜態方法,當父類中定義了一個靜態方法後,子類中應不要覆寫靜態方法,類中定義靜態方法或屬性應該通過類名直接存取,通過執行個體對象訪問靜態方法或屬性不是好的習慣;

34、建構函式應盡量簡化,否則可能會出現因初始化的時候變數的不一致;

35、避免在建構函式中初始化其他類

36、使用構造代碼塊精鍊程式:構造代碼塊會在每個不同參數的構造方法中都執行一次,先執行構造代碼塊,再執行構造方法,它並不是在建構函式之前啟動並執行,它依託於建構函式執行,我們可以把構造代碼塊運用到如下情境中:1:初始化執行個體變數2:初始化執行個體環境;

37、構造代碼塊會想你所想,在構造方法中使用this和super的時候,構造代碼塊已經替你考慮好了,如果在有參數構造方法中使用this(),是不會再重新執行構造代碼塊的,所以要靈活運用;

38、使用靜態內部類加強類的封裝性和提高了代碼的可讀性

39、使用匿名類的建構函式:new ArrayList(){};new ArrayList(){{}{}{}}

40、匿名類的建構函式很特殊;

41、靈活使用內部類,讓多重繼承成為現實;

42、讓工具類不可執行個體化最好的方式是:這樣也不能利用反射機制進行執行個體化

public class Utils{

private Utils(){

 Throws new Error(“don’t intstance me!!”);

}}

43、避免對象的淺拷貝:

Object提供的clone方法只是一種淺拷貝方式,也就是說它並不會把對象的所有屬性全部拷貝一份,而是有選擇性的拷貝,其拷貝規則如下:

基本類型:則拷貝其值

對象:拷貝地址引用,也就是說新拷貝出的對象與原有對象共用該執行個體變數,不受存取權限的限制。

String字串:拷貝的也是一個地址,是個引用,但是在修改時,它會從字串池(String pool)中重建新的字串,原有的字串對象保持不變,在此我們可以認為String是一個基本類型。

44、推薦使用序列化的方式實現對象的拷貝:參考我的博文,java對象的淺拷貝和深拷貝:http://blog.csdn.net/harderxin/article/details/41694747

45、覆寫equals方法時不要識別不出自己(見代碼)

//public boolean equals(Object obj) {//if(obj instanceof Person3){//Person3 p=(Person3)obj;//去掉trim()//return name.equalsIgnoreCase(p.getName().trim());//}//return false;//}

46、equals應該考慮null值情景

//  第二個版本----建議46//@Override//public boolean equals(Object obj) {//if(obj instanceof Person3){//Person3 p=(Person3)obj;//if(p.getName()==null||name==null){//return false;//}else{//return name.equalsIgnoreCase(p.getName().trim());//}//}//return false;//}

47、為了防止繼承,建議在equals中使用getClass進行類型判斷,而不是使用instanceOf

//  第三個版本----建議47@Overridepublic boolean equals(Object obj) {if(obj!=null&&obj.getClass()==this.getClass()){Person3 p=(Person3)obj;if(p.getName()==null||name==null){return false;}else{return name.equalsIgnoreCase(p.getName().trim());}}return false;}

48、覆寫equals方法必須覆寫hashcode方法:

     HashMap:底層處理機制是以數組的方式儲存Map條目(Map Entry)的,這其中的關鍵是這個數組下標的處理機制:依據傳入元素hashCode方法的返回值決定其數組的下標,如果該數組位置上已經有了Map條目,且與傳入的鍵值相等則不處理,若不相等則覆蓋;如果數組位置沒有條目,則插入,並加入到Map條目的鏈表中,同理,檢查鍵是否存在也是根據雜湊碼確定位置,然後遍曆尋找鍵值的。HashCode的值我們可以使用org.apache.commons.lang.builder包下的一個雜湊碼產生工具HashCodeBuilder產生

49、推薦覆寫toString方法:java提供預設的toString方法不友好,列印出來只有機器能看懂,其格式為類名+@+hashCode,所以建議覆寫toString方法,便於我們進行調試

50、使用package-info類為包服務:在需要用到包的地方,可以考慮一下這個特殊的類

51、不要主動進行記憶體回收:在應用程式中不要直接使用System.gc()來主動對垃圾進行回收,即使經常出現記憶體溢出也不要調用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.