Java代碼最佳化系列(一)開篇立碑

來源:互聯網
上載者:User

標籤:物件導向   最佳化   instanceof   java代碼最佳化   

轉載請註明出處:http://blog.csdn.net/lhy_ycu/article/details/45506549


在開篇之前,先補充一下《Java學習系列》裡面的instanceof關鍵字的使用及其陷阱。簡要說明:instanceof是一個簡單的二元操作符,它是用來判斷一個對象是否為一個類的執行個體。只要instanceof左右運算元有繼承或實現的關係,程式都是可以編譯通過的。下面通過一個簡單一實例來說明一下instanceof關鍵字的使用及其陷阱:

class A<T> {public boolean isDateInstance(T t) {return t instanceof Date;}}public class InstanceofTest {public static void main(String[] args) {// true。一個String對象是Object執行個體(java中Object是所有類的父類)System.out.println("zhangsan" instanceof Object);// false。Object是父類,它的對象明顯不是String類的執行個體System.out.println(new Object() instanceof String);// true。一個String對象是String的執行個體System.out.println(new String() instanceof String);// 編譯不能通過。'a' 為一個char類型,即基本類型// System.out.println('a' instanceof Character);// false。只要左運算元為null(本質是無類型),那麼結果就直接返回falseSystem.out.println(null instanceof String);// false。即使將null強轉也還是個nullSystem.out.println((String) null instanceof String);// 編譯不能通過。因為Date和String並沒有繼承或實現關係// System.out.println(new Date() instanceof String);// false。在編譯成位元組碼時,T已經是Object類型了,由於傳遞了一個"lisi"實參字串,所以T實際是String類型了。System.out.println(new A().isDateInstance("lisi"));}}
【注意】instanceof只能用於對象的判斷,不能用於基本類型的判斷。

下面開始正式進入主題,先從一個自增的陷阱開始吧。

1)自增的陷阱

int num = 0;for (int i = 0; i < 100; i++) {num = num++;}System.out.println("num = " + num);
列印結果是什麼呢?答案是0,為什麼呢?先看看執行步驟吧,程式第一次迴圈時的詳細步驟如下:JVM把num值(0)拷貝到臨時變數區,然後num值加1,這是num的值為1,接著返回臨時變數區的值,注意這個值是1沒修改過,最後將返回值賦給num,此時num的值被重設為了0。簡單說來就是int temp = num; num  += 1; return temp;這3步。所以列印結果還是0,num始終保持著原來的狀態。

最佳化:將num=num++; 修改為num++即可。


2)常量竟成變數?

大家想想,常量有可能成為變數嗎?答案是有可能,只不過這種做法是不被認同的。

public static final int RAND_CONST = new Random().nextInt();public static void main(String[] args) {// 通過列印幾次,可以看到結果變了,也就是說常量在定義的時候就沒有保證它的值運行期保持不變System.out.println("常量變了嗎?" + RAND_CONST);}
最佳化建議:務必常量的值在運行期保持不變,所以可以讓RAND_CONST在定義時直接賦值寫死。


3)“l” 你能看出這個字母是i的大寫、數字1還是字母l的小寫?

public static  long l = 11;

最佳化:字母后綴l盡量大寫L


4)三目運算子的類型不一致?

int i = 70;System.out.println(i < 100 ? 80 : 90.0);
列印結果出人意料,結果竟然為80.0,這是為什麼呢?i<100確實為true,但由於最後一個運算元為90.0,是一個浮點數,這時編譯器會將第二個運算元80轉為80.0浮點數,統一結果類型,所以列印結果為80.0。
最佳化:90.0改為90

5)不要重載含有變長參數的方法

簡要說明:變長參數必須是方法的最後一個參數,且一個方法不能定義多個變長參數。

public class Test01 {public static void fruitPrice(int price, int discount) {float realPrice = price * discount / 100.0F;System.out.println("非變長參數得出的結果:realPrice = " + realPrice);}public static void fruitPrice(int price, int... discounts) {float realPrice = price;for (int discount : discounts) {realPrice = price * discount / 100.0F;}System.out.println("變長參數得出的結果:realPrice = " + realPrice);}public static void main(String[] args) {fruitPrice(48888, 85);}}
列印結果是什麼呢?答案是:非變長參數得出的結果:realPrice = 41554.8,也就是程式執行的是第一個方法,而沒有執行變長參數方法,這是為什麼呢?因為Java在編譯時間,首先會根據實參的數量和類型(這裡是2個都是int類型的實參,注意沒有轉成int數組)來進行處理,也就是找到fruitPrice(int price, int discount)方法,而且確認它符合方法簽名條件,由於編譯器也愛“偷懶”,所以程式會執行第一個方法。

參考文獻:《編寫高品質代碼》機械工業出版社



Java代碼最佳化系列(一)開篇立碑

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.