2016-04-11 2 views
4

Может ли кто-нибудь сказать, почему я получаю java.lang.StackOverflowError, используя этот класс Kotlin? Строка 41 является if (instance == null) {StackOverflowError using Singleton in Kotlin

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, Котлин 1.0.1-2

+1

Если вы хотите сделать «TokenHelper» синглтон, просто объявите его как «object» и исключите свойство «instance» alltogether. Компилятор позаботится о шаблоне для вас. –

+0

@KirillRakhman Я считаю, что ваш комментарий - настоящий ответ. Теперь это объект, и я использую его как «TokenHelper.INSTANCE.getToken()» (в классе Java). – user3105453

+0

Я добавил его в качестве ответа. –

ответ

1

адаптировано из комментария на оригинальный ответ:

В Котлин, вам не нужно все шаблонного объявить одиночки. При объявлении своего класса, просто сделать его object так:

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

Затем откройте его следующим образом: TokenHelper.token или из Java TokenHelper.INSTANCE.getToken().

8

Вы звоните instance геттер рекурсивно. Изменение вы геттер определение использовать 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 () } компаньон объект { вала экземпляра: TokenHelper ленивого {Holder.INSTANCE} } ' Как вы думаете, что это Котлин совместимым тоже? Btw: Мой первоначальный код был создан AS при создании команды «Преобразовать в Kotlin». – user3105453

+1

Да, это соответствует требованиям. Преобразователь IDE хорошо работает для очень простых случаев - его результаты следует всегда проверять перед использованием. – miensol

+0

спас меня! Благодарю . –