在Kotlin中使用Singleton的StackOverflowError

use*_*453 4 android jetbrains-ide kotlin kotlin-android-extensions

任何人都可以说,为什么我要java.lang.StackOverflowError使用这个Kotlin课程?第41行是if (instance == null) {

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
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

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 
Run Code Online (Sandbox Code Playgroud)

Android Studio 2.0,Kotlin 1.0.1-2

mie*_*sol 8

instance递归地调用getter方法.更改要使用的getter定义field:

var instance: TokenHelper? = null
    get() {
        if (field == null) {
            field = TokenHelper()
        }
        return field
    }
Run Code Online (Sandbox Code Playgroud)

文件中的相关摘录:

Kotlin中的类不能有字段.但是,有时在使用自定义访问器时需要有一个支持字段.出于这些目的,Kotlin提供了一个自动支持字段,可以使用字段标识符访问该字段:

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

字段标识符只能在属性的访问者中使用.


Kir*_*man 1

改编自对原始答案的评论:

在 Kotlin 中,您不需要所有样板来声明单例。声明你的类时,只需将其设置为object如下所示:

object TokenHelper {
    var token: String? = null
    var appId: String? = null
    var installationId: String? = null
    var userId: String? = null
}
Run Code Online (Sandbox Code Playgroud)

然后按如下方式访问它:TokenHelper.token或从 Java TokenHelper.INSTANCE.getToken()