StackOverflowError con Singleton en Kotlin

¿Alguien puede decir por qué estoy obteniendo un java.lang.StackOverflowError usando esta class de Kotlin? La línea 41 es 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 } } } 

Stacktrace:

 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 Studio 2.0, Kotlin 1.0.1-2

Adaptado de un comentario sobre la respuesta original:

En Kotlin, no necesita todos los repetidores para declarar un singleton. Al declarar tu class, simplemente haz que sea un object como ese:

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

Luego acceda a esto de la siguiente manera: TokenHelper.token o desde Java TokenHelper.INSTANCE.getToken() .

Estás llamando al método getter de instance recursivamente. Cambia la definición de getter para usar el field lugar:

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

El extracto relevante de la documentation:

Las classs en Kotlin no pueden tener campos. Sin embargo, a veces es necesario tener un campo de respaldo cuando se usan accesadores personalizados. Para estos fines, Kotlin proporciona un campo de respaldo automático al que se puede acceder usando el identificador de campo:

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

El identificador de campo solo se puede usar en los descriptores de acceso de la propiedad.