1. 程式人生 > >從結構上分析Java中的 if/else與switch的區別

從結構上分析Java中的 if/else與switch的區別

聽同事說了一句能用if/else就別用switch,感覺這就話不對,但是又提不出什麼依據進行判斷,不能明白其中是不是有什麼深層次的原因,今天就探究一下這方面的原因。我們要明白我們的程式到底是誰幫助我們做的?

我們首先得明白計算機的五大組成部分控制器,運算器,儲存器,輸入,輸出。我們的程式排程其實是運算器在幫助我們進行做的,我們的Java程式碼其實到最後真正執行的就是一串串指令,而其中在其中有一些不同特殊的指令,今天我們要說的就是跳轉指令,其中跳轉指令又分為有條件條件轉,與無條件跳轉。

所謂的跳轉指令在我們的Java語言體系中也就是我們今天要說的if else,但是switch則不一樣,switch的具體實現根據不同系統的實現有關,如果分支比較少的話會轉換為跳轉指令,但是如果是分支比較多的話則會轉換為跳轉表的方式。

在判斷比較多的時候,如果還是跳轉指令會進行很多次的比較運算,因為我們指令在執行的時候回從暫存器裡面來回的進行取值壓值,這樣其實是比較浪費時間的,這個時候會轉換為另一種更為高效的方式,稱之為跳轉表,跳轉表其實是一個對映表存貯的是值與程式碼塊的位置。

話又說過來了,為什麼跳轉表就是很快了,因為其中的值必須是整數值,並且是按照大小順序進行排序,使用高效的二分查詢法,沒查詢一次就省略一半的時間。如果值是連續的,switch還會轉換為陣列,這下連找就不用找了,直接定位到位置,就算不是連續的,如果是密集的數值的話,也是會轉換為一個數組型別的跳轉表。

另外在我們的原始碼中的值判斷是不會進行排序的,我們考慮過是什麼時候進行排序呢?是在執行的時候Java虛擬機器幫我們做這件事,還是在編譯的時候呢,因為這本來就是靜態的資源,是可以在編譯的時候進行確認的。另外 bate/char/int ,short,列舉都能使用,string也能行,但是long不行,因為跳轉表的一片區域的空間一半是32位,而long64,放不下嘍。而到了String這個怎麼排序呢,我們大家知道就算相同的字串其實他的hashCode的值是可能衝突的這個時候h會拉出一個連結串列對他再次進行判斷。

另外雖然經過最近幾個版本的擴充套件中,switch可以使用列舉,String,其實在底層,還是隻支援四種類型。只不過在編譯的時候對新增的幾種型別做了處理,處理成了四種類型。

針對於包裝型別,switch則是對其經過了拆箱的的過程進行處理。

if與else與switch中的區別就是我們擼碼中比較常見的與空間換時間,時間換空間的最經典的例子,在我們開發中當你發現你的程式碼無懈可擊的時候,恰恰是最不適合的,我們沒有最優的技術 只有最合適自己的技術。

另外如果我們的程式碼中如果存在了過多的if判斷,會影響我們程式碼的可讀性,另外過多的if中你也從另一個方面證明了,你的設計可能是有問題呢。可以選用策略模式,職責鏈模式,代理模式都可以解決這些問題。