您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關在Java中怎么避免創建不必要的對象,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
在Java開發中,程序員要盡可能的避免創建相同的功能的對象,因為這樣既消耗內存,又影響程序運行速度。在這種情況下可以考慮重復利用對象。
接下來舉例幾種對象重復利用的場景,看看我們是不是有中招了,如果有趕緊趁著還沒被發現悄悄改掉,被發現了會被diss啦!
如下兩種寫法看似沒有什么區別,但是如果深入jvm底層了解,我們可以利用jvm運行時常量池的特性,避免創建具有相同功能的String對象(尤其是在循環內部創建)可以帶來比較可觀的性能優化以及節約內存。
錯誤寫法
// 每次都會創建一個新的String對象,且不會加入常量池 String name2 = new String("李子捌");
正確寫法
// 正確寫法 String name1 = "李子捌";
除此之外,剛寫Java代碼的程序員們,也要正確的選擇String、StringBuilder、StringBuffer類的使用。String為不可變對象,通常用于定義不變字符串;StringBuilder、StringBuffer用于可變字符串操作場景,如字符串拼接;其中StringBuffer是線程安全的,它通過Synchronized關鍵字來實現線程同步。
// StringBuffer中的append()方法 public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } // StringBuilder中的append()方法 public StringBuilder append(String str) { super.append(str); return this; }
Boolean是常用的類型,在開發中也應該使用Boolean.valueof()而不是new Boolean(),從Boolean的源碼可以看出,Boolean類定義了兩個final static的屬性,而Boolean.valueof()直接返回的是定義的這兩個屬性,而new Boolean()卻會創建新的對象。
public static final Boolean TRUE = new Boolean(true); public static final Boolean FALSE = new Boolean(false);
Java提供了基本數據類型的自動拆箱和裝箱功能,那是不是意味著我們可以在代碼中隨意的使用這兩個類型呢?其實理論上在代碼層面是沒得問題,不過在具體的性能方面還是有優化的空間啦!!!
我們來測試下性能
long start = System.currentTimeMillis(); Integer sum = 0; for (int i = 0; i < 100000; i++) { sum += i; } System.out.println(System.currentTimeMillis() - start);
使用Integer耗時3毫秒
long start = System.currentTimeMillis(); // 修改Integer 為 int int sum = 0; for (int i = 0; i < 100000; i++) { sum += i; } System.out.println(System.currentTimeMillis() - start);
使用int耗時0毫秒
因此關于自動拆箱裝箱的使用,我們其實也可以做適當的考慮,畢竟有時候代碼性能就是一點點擠出來的嘛!!!
正則表達式我們經常用于字符串是否合法的校驗,我們先來看一段簡單的代碼(大家有沒有一眼看出問題呢?我想你肯定看出來了!!!):
public static void main(String[] args) { String email = "1057301174@qq.com"; String regex = "^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$"; long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { email.matches(regex); } System.out.println(System.currentTimeMillis() - start); }
執行這段代碼的時間,一共耗時71毫秒,看似好像挺快的!
但是我們做個非常簡單的優化,優化后的代碼如下所示:
public static void main(String[] args) { String email = "1057301174@qq.com"; String regex = "^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$"; Pattern pattern = Pattern.compile(regex); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { //email.matches(regex); pattern.matcher(email); } System.out.println(System.currentTimeMillis() - start); }
再次執行代碼,一共耗時1毫秒,快了70倍呀!!!
這是因為String.matches()方法在循環中創建時,每次都需要執行Pattern.compile(regex),而創建Patter實例的成本很高,因為需要將正則表達式編譯成一個有限狀態機( finite state machine)。這種我們經常會因為Java api提供了比較方便的方法調用而忽略了性能考究,往往不容易被發現。
關于“在Java中怎么避免創建不必要的對象”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。