30 個java編程技巧(最佳實踐的初學者)

1.return 一個空的集合,而不是 nulljava

若是一個程序返回一個沒有任何值的集合,請確保一個空集合返回,而不是空元素。這樣你就不用去寫一大堆 」if else」 判斷null元素。mysql

30 個java編程技巧(最佳實踐的初學者)一

Java 的標準庫設計者已經在 Collections 類中放了一個空的 List 常量 EMPTY_LIST,除此以外,還有 EMPTY_MAP, EMPTY_SET,真是貼心。sql

2. 當心使用 String數據庫

由於字符串相加或者拼接的方式都會在對象池中查找字符串是否存在,若是不存在則建立,這樣在拼接的過程當中會產生大量中間過程的字符串,佔用內存資源。StringBuilder效率優於StringBuffer,可是StringBuffer線程安全。編程

30 個java編程技巧(最佳實踐的初學者)一
30 個java編程技巧(最佳實踐的初學者)一
另外,在實例化一個字符串對象,構造函數應該避免發生直接實例化,例如:
30 個java編程技巧(最佳實踐的初學者)一

3. 避免沒必要要的對象數組

一個最昂貴的操做(在內存利用率)是java對象的建立。所以,建議只在必要時建立或初始化對象。下面的代碼給出了一個例子:安全

30 個java編程技巧(最佳實踐的初學者)一
4.Array 和ArrayList 選擇

ArrayList和Array是咱們在實際編程中常用的容器,並且由於ArrayList至關於動態化的數組,因此它們之間有太多的類似,以致於咱們在選擇哪一種來存儲元素的時候,會有小小的迷惑,他們都有註解的優缺點,選擇真的取決於你的真實場景。函數

30 個java編程技巧(最佳實踐的初學者)一

4.1.Array 有固定大小但 ArrayList 的大小不一樣。因爲Array 的大小是固定的,在Array 類型變量聲明的時候,內存被分配。所以,Array 是很是快的。另外一方面, 使用ArrayList的最大缺點就是當咱們添加新的元素的時候,它是先檢查內部數組的容量是否足夠,若是不夠,它會建立一個容量爲原來數組兩倍的新數組,���後將全部元素複製到新數組裏,接着拋掉舊數組。這點真的很麻煩,由於每次都要這麼搞,尤爲是元素足夠多的時候,這就真的是既影響內存又影響效率的問題,但經過單獨測試它們的運行時間,發現其實差很少,最大的影響就是若是是有其餘代碼也須要使用到內存,那麼Array依然不變,可是ArrayList就會變得慢多,相同狀況下所花的時間是Array的四倍多(實際狀況是遠遠不止)。性能

4.2.這是添加或刪除元素從ArrayList 比Array更容易。測試

4.3.數組能夠多維但ArrayList只有一個維度。

4.4.ArrayList由於內部是一個數組,因此它是能夠轉化爲數組的。

4.5 二者的適用場合:

List list = new ArrayList();

雖然咱們想要的確實是ArrayList而不是list,可是咱們知道,父類是能夠得到子類的引用而且使用子類的方法,因此這樣咱們就能同時使用List和ArrayList的方法而不用懼怕出錯了。

首先,一個重要的約束就是,List的聲明區域通常是在main方法裏(固然靜態list也能夠,可是咱們通常使用的時候都只是當作存儲元素的臨時容器),而Array是能夠在外部進行聲明的,這時它就是全局數組。因此,單看這點,它們的使用已經有區別,若是想要保存一些在整個程序運行期間都會存在並且不變的數據,咱們能夠將它們放進一個全局數組裏,可是若是咱們單純只是想要以數組的形式保存數據,方便咱們進行查找,那麼,咱們就選擇ArrayList。並且還有一個地方是必須知道的,就是若是咱們須要對元素進行頻繁的移動或刪除,或者是處理的是超大量的數據,那麼,使用ArrayList就真的不是一個好的選擇,由於它的效率很低,使用數組進行這樣的動做就很麻煩,那麼,咱們能夠考慮選擇LinkedList。

30 個java編程技巧(最佳實踐的初學者)一

5.用try catch的時候,要加finally嗎?

考慮下面的代碼片段

30 個java編程���巧(最佳實踐的初學者)一
運行結果:

在Finally代碼塊中

在Finally代碼塊中

在Finally代碼塊中

在Finally代碼塊中

在Try內部代碼塊,退出不執行Finally代碼塊

在運行代碼前,它看起來像要打印 」在Finally代碼塊中「 5次。可是執行的結果只有4次。第五次打印的結果是 」在Try內部代碼塊,退出不執行Finally代碼塊「。

關於 Java 虛擬機是如何編譯 finally 語句塊的問題,有興趣的讀者能夠參考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 節 Compiling finally。那裏詳細介紹了 Java 虛擬機是如何編譯 finally 語句塊。實際上,Java 虛擬機會把 finally 語句塊做爲 subroutine(對於這個 subroutine 不知該如何翻譯爲好,乾脆就不翻譯了,省得產生歧義和誤解。)直接插入到 try 語句塊或者 catch 語句塊的控制轉移語句以前。可是,還有另一個不可忽視的因素,那就是在執行 subroutine(也就是 finally 語句塊)以前,try 或者 catch 語句塊會保留其返回值到本地變量表(Local Variable Table)中。待 subroutine 執行完畢以後,再恢復保留的返回值到操做數棧中,而後經過 return 或者 throw 語句將其返回給該方法的調用者(invoker)。

將上面代碼修改以下:

30 個java編程技巧(最佳實踐的初學者)一
運行結果:

在Try內部代碼塊,退出不執行Finally代碼塊

在Try內部代碼塊,退出不執行Finally代碼塊

在Try內部代碼塊,退出不執行Finally代碼塊

在Try內部代碼塊,退出不執行Finally代碼塊

在Try內部代碼塊,退出不執行Finally代碼塊

總結:

這裏就不過多的去具體分析整個過程有興趣的朋友可找資料瞭解整個過程,一個小小的、看似簡單的 finally 語句塊背後竟然隱藏了這麼多玄機。看來,咱們平時仍是應該認真的閱讀 Java 相關的基礎文檔,好比:Java 語言規範、Java 虛擬機規範等,不少棘手的問題均可以從中獲得答案。只有真正的吃透了基礎知識,才能達到運用自如的境界!

1> try、catch、finally語句中,在若是try語句有return語句,則返回的以後當前try中變量此時對應的值,此後對變量作任何的修改,都不影響try中return的返回值

2> 若是finally塊中有return 語句,則返回try或catch中的返回語句忽略。

3 >若是finally塊中拋出異常,則整個try、catch、finally塊中拋出異常

因此使用try、catch、finally語句塊中須要注意的是

1> 儘可能在try或者catch中使用return語句。經過finally塊中達到對try或者catch返回值修改是不可行的。

2 >finally塊中避免使用return語句,由於finally塊中若是使用return語句,會顯示的消化掉try、catch塊中的異常信息,屏蔽了錯誤的發生

3 >finally塊中避免再次拋出異常,不然整個包含try語句塊的方法回拋出異常,而且會消化掉try、catch塊中的異常

6.奇數判斷

看看下面的代碼行,並肯定若是他們能夠用來精確地識別一個給定的數字是不是奇數?

30 個java編程技巧(最佳實踐的初學者)一

奇數能夠被定義爲被2整除餘數爲1的整數。表達式 num% 2 計算的是 num整除 2 時所產生的餘數,所以看起來這個程序應該可以正確運轉。遺憾的是,它不能;它在四分之一的時間裏返回的都是錯誤的答案。

爲何是四分之一?由於在全部的 int 數值中,有一半都是負數,而 isOdd 方法對於對全部負奇數的判斷都會失敗。在任何負整數上調用該方法都回返回 false ,無論該整數是偶數仍是奇數。

這是 Java 對取餘操做符(%)的定義所產生的後果。該操做符被定義爲對於全部的 int 數值 a 和全部的非零 int 數值b,都知足下面的恆等式:

(a / b) * b + (a % b) == a

如今進行修改以下:

30 個java編程技巧(最佳實踐的初學者)一

使用此代碼,不只是解決了奇數的負的問題,並且這個代碼也高度優化。由於,算術和邏輯運算的速度更快,比除法和乘法,結果取得了更快。

7. 單引號和雙引號之間的區別

30 個java編程技巧(最佳實踐的初學者)一

嘗試運行上面的程序。這個程序演示了一個死鎖。這種死鎖的產生是由於兩個線程都在等待其餘線程所抓取的資源。他們都不在任何一個版本。從代碼,彷佛還「HaHa」是回來了,但它實際上返回ha169。緣由是,若是使用雙引號,字符串對待,但在單引號的狀況下,字符自動轉換爲int型,進行計算。

8. 經過簡單的技巧避免內存泄漏

內存泄漏常常會致使軟件的性能退化。由於,java自動管理內存,開發商沒有太多的控制。但仍有一些標準的作法,能夠用來防止內存泄漏。

當查詢完成時,老是釋放數據庫鏈接。

儘可能使用 Finally 塊。

釋放存儲在靜態表中的實例。

9. 避免死鎖

死鎖出現的緣由有不少。避免死鎖不是一句話就能解決的。一般來講,當某個同步對象在等待另外一個同步對象所擁有的資源上的鎖時,便會產生死鎖。

試着運行下下面的程序。它會告訴你什麼是死鎖。這個死鎖是因爲兩個線程都在等待對方所擁有的資源,所以會產生死鎖。它們會一直等待,沒有誰會先放手。

30 個java編程技巧(最佳實踐的初學者)一
30 個java編程技巧(最佳實踐的初學者)一
30 個java編程技巧(最佳實踐的初學者)一

運行結果:

Addition Thread: 13

Subtraction Thread: 7

Holding First Lock…

Holding Second Lock…

Addition Thread: Waiting for AddLock…

Subtraction Thread: Waiting for SubLock…

但若是調用的順序變一下的話,死鎖的問題就解決了。

將 MySubtractionThread中的線程加鎖順序調換再看看

30 個java編程技巧(最佳實踐的初學者)一

運行結果:

Addition Thread: 13

Holding First Lock…

Addition Thread: Waiting for AddLock…

Threads: Holding Add and Sub Locks…

Subtraction Thread: 7

Holding Second Lock…

Subtraction Thread: Waiting for SubLock…

Threads: Holding Add and Sub Locks…

三種用於避免死鎖的技術:

1>加鎖順序

2>加鎖時限

3>死鎖檢測

一個更好的方案是給這些線程設置優先級,讓一個(或幾個)線程回退,剩下的線程就像沒發生死鎖同樣繼續保持着它們須要的鎖。若是賦予這些線程的優先級是固定不變的,同一批線程老是會擁有更高的優先級。爲避免這個問題,能夠在死鎖發生的時候設置隨機的優先級。

10.JAVA運行內存的設置

一些java應用程序能夠被高度的CPU密集型以及他們須要不少內存。這樣的應用程序一般運行速度慢,由於內存高的要求。因此,咱們能夠在相關的配置文件中進行修改調整內存大小。

Xms = 設置內存初始化的大小

Xmx = 設置最大可以使用內存的大小

XX:PermSize =初始大小,將分配給JVM的啓動過程

XX:MaxPermSize = 最大尺寸能夠分配JVM的啓動過程

11. 如何在java時間操做

有java時間兩種標準方法:

System.currentTimeMillis()、System.nanoTime()

平時產生隨機數時咱們常常拿時間作種子,好比用System.currentTimeMillis的結果,可是在執行一些循環中使用了System.currentTimeMillis,那麼每次的結果將會差異很小,甚至同樣,由於現代的計算機運行速度很快。後來看到java中產生隨機數函數以及線程池中的一些函數使用的都是System.nanoTime。

>System.currentTimeMillis返回的是從1970.1.1 UTC 零點開始到如今的時間,精確到毫秒,平時咱們能夠根據System.currentTimeMillis來計算當前日期,星期幾等,能夠方便的與Date進行轉換,

> System.nanoTime提供相對精確的計時,可是不能用他來計算當前日期,

因此在使用中,咱們能夠根據咱們具體的目的去正確的選擇他們。

12. Float 和Double的選擇

Data type Bytes used Significant figures (decimal)
Float 4 7
Double 8 15

double應該比float更好用,緣由:

大多數處理器須要幾乎相同數量的處理時間來執行浮點和雙運算的操做。在相同數量的計算時間雙提供了更高的精度。

13. Java的乘方運算

java提供了兩個方法:

Multiplication:乘法

30 個java編程技巧(最佳實踐的初學者)一

pow(double base, double exponent):(base的exponent次方)

30 個java編程技巧(最佳實踐的初學者)一
math.pow只應在必要時使用,像指數是一個分數。Math.pow()方法一般慢300-600倍的速度比乘法。

14. 如何處理空指針異常

空指針異常在java中是很常見的。當咱們嘗試調用一個空對象引用的方法時,這個異常會發生。例如:

30 個java編程技巧(最佳實踐的初學者)一
若是在上面的例子中,若是獲得一個NullPointerException異常,而後學校 是null 或liststudents()null。有個好注意你能夠提前將異常拋出,經過提前拋出異常(又���"迅速失敗"),異常得以清晰又準確堆棧信息當即反映出什麼出了錯(提供了非法參數值),爲何出錯(文件名不能爲空值),以及哪裏出的錯,菜鳥和高手均可能犯的一個錯是,在程序有能力處理異常以前就捕獲它。Java編譯器經過要求檢查出的異常必須被捕獲或拋出而間接滋長了這種行爲。天然而然的作法就是當即將代碼用try塊包裝起來,並使用catch捕獲異常,以避免編譯器報錯。
30 個java編程技巧(最佳實踐的初學者)一
 
0
相關文章
相關標籤/搜索