本文由咕咚發佈在我的博客,轉載請註明出處。html
本文永久地址:https://gudong.name/2019/11/04/use-enum-or-not.htmljava
在 Android 官方文檔推出性能優化的時候,從一開始有這樣一段說明:android
Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.web
意思是說在 Android 平臺上 avoid 使用枚舉,由於枚舉類比通常的靜態常量多佔用兩倍的空間。數組
若是你還不瞭解枚舉,參看文章 枚舉介紹以及枚舉的本質。性能優化
因爲枚舉最終的實現原理仍是類,在編譯完成後,最終爲每一種類型生成一個靜態對象,而在內存申請方面,對象須要的內存空間遠大於普通的靜態常量,並且分析枚舉對象的成員變量可知,每個對象中默認都會有一個字符數組空間的申請,計算下來,枚舉須要的空間遠大於普通的靜態變量。具體分析可見這篇文章。app
因此,照此來看,在 Android 這樣對內存寸土必爭的平臺上,若是隻是使用枚舉來標記類型,那使用靜態常量確實更優,可是如今翻看官方文檔發現,這個建議已經被刪除了。(post
爲何官方會刪除?難道是以前的建議有錯誤嗎,或者描述的不夠精確?性能
我的認爲,枚舉佔用空間比普通類型的靜態常量大,這是事實,沒問題,可是據此就建議不在 Android 中使用時不妥的,具體看 JakeWharton 在 reddit 上的一個評論。優化
The fact that enums are full classes often gets overlooked. They can implement interfaces. They can have methods in the enum class and/or in each constant. And in the cases where you aren't doing that, ProGuard turns them back into ints anyway.
The advice was wrong for application developers then. It's remains wrong now.
最重要的一句是
ProGuard turns them back into ints anyway.
在開啓 ProGuard 優化的狀況下,枚舉會被轉爲 int 類型,因此內存佔用問題是能夠忽略的。具體可參看 ProGuard 的優化列表頁面 Optimizations Page,其中就列舉了 enum 被優化的項,以下所示:
class/unboxing/enum
Simplifies enum types to integer constants, whenever possible.
既然 ProGuard 會把枚舉優化爲整形,那是否是在 Android 中,就能夠繼續無所顧忌的使用枚舉了呢?😊
並非!!!
ProGuard 對枚舉的優化有必定的限制條件,若是枚舉類存在以下的狀況,將不會有優化爲整形,以下所示:
參考自:ProGuard 初探 · dim's blog,另外,上面的這七種狀況,我並無找到官方的說明,若是有哪位讀者知道,請在評論區裏留下連接,謝謝啦~
也就是說,要保證枚舉能被正常優化爲整形,就要確保枚舉足夠簡單,以下所示,這些狀況下的枚舉都是能夠被優化的
enum Color{ Red,Black,Green }
或者這樣的
enum Date { Sunday("星期日"), Monday("星期一"), Tuesday("星期二"), Wednesday("星期三"), Thursday("星期四"), Friday("星期五"), Saturday("星期六"); public String value; private Date(String value) { this.value = value; } }
可是再次查看那七條規則,會發現這幾個規則幾乎把枚舉面向對象的特性都限制了,在這樣的限制下,枚舉好用的地方都將消失,失去了枚舉的靈活性。
到這裏就有點矛盾了,枚舉很好用,ProGuard 也會對它進行優化,可是優化條件限制了咱們更好的使用枚舉,那咱們應該怎麼面對這種狀況,個人幾點建議:
至於 Android 爲何會把那條優化建議刪掉,我認爲官方也是考慮到了枚舉會被優化爲整形這一點,因此纔去掉的。
而後實際工做中具體怎麼使用,官方就不在說 」avoid「 了,而是讓開發者自行決定是否是使用枚舉。
以上就是關於 [Android 開發中是否應該使用枚舉?] 這個問題個人一些思考。
咕咚,Android 工程師,我的博客 gudong.name,公衆號:咕喱咕咚