發佈更新 9/27:改正了讀者指出的錯誤。謝謝你們!還有什麼錯誤和不足儘管指出!java
本文中方法適用與Android Studio
和IntelliJ Idea
windows
咱們寫代碼的時候常常要寫個單例,其實在Android Studio中能夠快速寫一個單例的方法有不少。函數
File
-> New
-> Singleton
。spa
這是生成單例代碼的一個例子。code
public class Test {
private static Test ourInstance = new Test();
public static Test getInstance() {
return ourInstance;
}
private Test() {
}
}複製代碼
謝謝讀者提醒!這裏寫錯了!這裏保留原文。下面正文更正!下面代碼和模版代碼同時更正,但因篇幅緣由,代碼保留原文了!cdn
原文:這個單例有幾個缺點。getInstance沒有對ourInstance進行空判斷,因此可能返回null。若是加上空判斷,並在其內部若是實例化一個對象就又有一個問題,若是不一樣步的話可能產生多個對象。因此,Android Studio爲咱們提供的這個方法並很差。我但願的是這個樣子的:對象
上面單例是直接賦值的,可是一般,咱們都是使用的時候纔去賦值,因此一般狀況下是下面這個樣子。blog
public class Test {
private static Test instance ;
public static Test getInstance() {
if (instance == null) {
synchronized (Test.class) {
if (instance == null) {
instance = new Test();
}
}
}
return instance;
}
private Test() {
}
}複製代碼
既然需求默認的需求不能實現咱們的要求,那麼,去自定義單例模版。在 Preference
->Editor
->File and Code Templates
能夠找到建立各類File
的模版。如圖:接口
咱們選擇單例,而後在右邊的編輯區就能夠編寫本身的代碼模版。圖片
那麼我這裏提供一套代碼模版給你們,若是你不肯意本身寫,直接把個人複製粘貼過去就好了。
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
public class ${NAME} {
private static ${NAME} instance ;
public static ${NAME} getInstance() {
if (instance == null) {
synchronized(${NAME}.class){
if (instance == null) {
instance = new ${NAME}();
}
}
}
return instance;
}
private ${NAME}() {
}
}複製代碼
而後咱們使用這個模版再試一下:
就是咱們想要的代碼。怎麼樣?可是這樣並不老是符合咱們的使用場景。咱們有的時候,在建立一個類的時候並無想好它就是一個單例。有的時候是對一個現有的類的改造。但咱們總不能再從新去建立一個吧。
那麼好。看下面。
這個我在我以前的,Android Studio相見恨晚的操做錦集中已經講過一次了,可是爲了防止沒有看過那篇文章的讀者我再講一遍。
自定義活動模版的入口:
Prefrence
->Editor
->Live Templates
,下面就是整個界面的一些介紹。
例如我已經在user
組中建立好了本身的singleton
活動模版。若是是大家,能夠按照下面步驟作:
+
建立一個新的活動模版Edit variables
中編輯函數式固然我已經編寫好了活動模版代碼,我貼在這裏,你能夠直接複製粘貼到本身的裏面:
private static $SELECTION$ instance ;
private $CLASS_NAME$($param1$){
$init$
}
public static $SELECTION$ getInstance($param1$){
if (instance == null) {
synchronized ($CLASS_NAME$.class){
if (instance == null) {
instance = new $CLASS_NAME$($param2$) ;
}
}
}
return instance ;
}複製代碼
注意 下面一步很關鍵
複製完以後。點擊Edit variables
;在CLASS_NAME
對應的後面一格填寫表達式className()
。如圖。
好了大功告成!
首先說一下,在咱們公司,JavaBean的賦值都是經過依賴注入的方式。幾乎每個JavaBean都提供了一個接口,單例也是。固然我上面的活動模版也是針對這種狀況編寫的,併兼容不是依賴注入的狀況。
那麼好咱們看一個例子:
咱們將一個現有的Test類改形成一個單例;
public class Test implements ITest {
private static final String TAG = Test.class.getSimpleName();
public Test(String test) {
init(test);
}
private void init(String test) {
Log.d(TAG, "init: " + test);
}
}複製代碼
咱們的目標應該是將其改形成這樣:
public class Test implements ITest {
private static final String TAG = Test.class.getSimpleName();
private static ITest instance;
private Test(String test) {
init(test);
}
public static ITest getInstance(String test) {
if (instance == null) {
synchronized (Test.class) {
if (instance == null) {
instance = new Test(test);
}
}
}
return instance;
}
private void init(String test) {
Log.d(TAG, "init: " + test);
}
}複製代碼
OK,那麼看看使用咱們的活動模版怎麼作吧!
Surround With
,快捷鍵Alt+Command+T
(若是你是windows
,或者快捷鍵不是這個,看下圖,你能夠雙擊shift
鍵,輸入surround with
查看,若是你的紅框部分沒有東西,本身去keymap中去設置吧)singleton
活動模版。就會生成好大部分代碼。public
構造方法沒有刪除。這一步就是刪除原來的public
方法那麼好,在錄製的時候我故意在關鍵的地方放慢了速度,不然能夠更快。這樣是否是能夠很快的改造一個單例類了!
我發現個人文章老是被轉成圖片在微博中轉發,在這裏很是感謝你們的賞識。我也但願本身能夠給你們分享更多精彩的文章。其實本身在分享的同時也收穫了不少。
可是轉成圖片,就看不到動圖的效果了。有些操做的演示仍是很依賴動圖展現的。不過我看轉發我文章的人都會附上原文連接,我在這裏,很是建議你們去看原文。我保證原文更加精彩。
若是你只看到了圖片,那也無所謂了,個人文章暫時也沒有維權呢,那些不帶原文連接和做者信息的人,他們轉就轉吧,他們開心就好。若是對咱們文章感興趣能夠到 掘金 中搜索做者,柴澤建_Jack,就能夠查看個人文章了。
「做者好菜連個連接都不會放嗎?」
「若是生成了圖片大家會去敲連接嗎?」
「會!」
哈哈!我就是「一個逗逼,一個Android開發者,一個持續分享技術乾貨的小浪逼。」
我其它可能與本文相關的文章。
教你把Java Bean擼成串的最快方法-自定義setter生成腳本