2016-04-11 67 views
4

任何人都可以告訴我,爲什麼我要使用這個Kotlin類獲得java.lang.StackOverflowError? 41號線是if (instance == null) {StackOverflowError在Kotlin中使用Singleton

class TokenHelper protected constructor() { 
    var token: String? = null 
    var appId: String? = null 
    var installationId: String? = null 
    var userId: String? = null 

    companion object { 
     var instance: TokenHelper? = null 
      get() { 
       if (instance == null) { 
        instance = TokenHelper() 
       } 
       return instance 
      } 
    } 
} 

堆棧跟蹤:

04-11 19:07:42.188 16142-16142/com.foo.bar.debug E/AndroidRuntime: FATAL EXCEPTION: main 
    Process: com.foo.bar.debug, PID: 16142 
    java.lang.StackOverflowError: stack size 8MB 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:0) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
     at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41 
04-11 19:07:42.271 16142-16142/com.foo.bar.debug D/Error: ERR: exClass=java.lang.StackOverflowError 
04-11 19:07:42.271 16142-16142/com.foo.bar.debug D/Error: ERR: exMsg=stack size 8MB 
04-11 19:07:42.271 16142-16142/com.foo.bar.debug D/Error: ERR: file=TokenHelper.kt 
04-11 19:07:42.271 16142-16142/com.foo.bar.debug D/Error: ERR: class=com.foo.bar.helper.TokenHelper$Companion 
04-11 19:07:42.271 16142-16142/com.foo.bar.debug D/Error: ERR: method=getInstance line=0 
04-11 19:07:42.282 16142-16142/com.foo.bar.debug D/Error: ERR: stack=java.lang.StackOverflowError: stack size 8MB 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:0) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(TokenHelper.kt:41) 
    at com.foo.bar.helper.TokenHelper$Companion.getInstance(
04-11 19:07:42.283 16142-16142/com.foo.bar.debug D/Error: ERR: TOTAL BYTES WRITTEN: 880768 
04-11 19:07:45.527 16142-16142/com.foo.bar.debug D/Process: killProcess, pid=16142 
04-11 19:07:45.528 16142-16142/com.foo.bar.debug D/Process: com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:113 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 

的Android 2.0工作室,科特林1.0.1-2

+1

如果你想讓'TokenHelper'成爲一個singleton,只需將它聲明爲'object'並將'instance'屬性全部放在一起即可。編譯器會照顧你的樣板。 –

+0

@KirillRakhman我相信你的評論是真正的答案。現在它是一個對象,我使用它像'TokenHelper.INSTANCE.getToken()'(在Java類中)。 – user3105453

+0

我將其添加爲答案。 –

回答

1

從原來的答案評論改編:

在科特林,你並不需要所有的樣板申報單。當你的聲明類,只是使它成爲object像這樣:TokenHelper.token或從Java TokenHelper.INSTANCE.getToken()

object TokenHelper { 
    var token: String? = null 
    var appId: String? = null 
    var installationId: String? = null 
    var userId: String? = null 
} 

如下然後訪問它。

8

你調用遞歸instance getter方法。改變你的getter定義中使用field代替:

var instance: TokenHelper? = null 
    get() { 
     if (field == null) { 
      field = TokenHelper() 
     } 
     return field 
    } 

相關摘自文檔:

類在科特林不能有領域。但是,在使用自定義訪問器時,有時需要使用 才能擁有後臺字段。對於 這些目的,科特林提供可 使用字段識別符訪問的自動支持字段:

var counter = 0 // the initializer value is written directly to the backing field 
    set(value) { 
    if (value >= 0) 
     field = value 
    } 

字段的標識符只能在屬性的訪問中使用。

+1

謝謝。我剛剛搜索了「Kotlin Singleton」並提出了這個解決方案(https://medium.com/@adinugroho/singleton-in-kotlin-502f80fd8a63#.64ssyu1by): '私人對象持有者val INSTANCE = TokenHelper( ) } 同伴對象{ VAL實例:通過TokenHelper懶{} Holder.INSTANCE} ' 你認爲這是科特林兼容嗎? Btw:我的初始代碼是由AS在生成「Convert to Kotlin」命令時生成的。 – user3105453

+1

是的,它符合標準。 IDE轉換器適用於非常簡單的情況 - 它的輸出應該在使用前始終檢查。 – miensol

+0

救了我!謝謝 。 –