Kotlin - Property must be initialized or be abstract even if there is an init() function

16,573

Solution 1

Before using lateinit, you must understand what that means.

Your variables are not initialized properly. Various ways to solve that problem:

  • Initialize the variables inside the constructor or a proper init block (not a private function as you declared it)
  • Initialize the variables at the same time as you declare them
  • Initialize the variables later and let Kotlin know that (this is the lateinit keyword)

Those 3 options are not equivalent, and depending on your code, the two first ones may be more appropriate than the third one.

lateinit will make your app crash if you access the variables before they are actually initialized.

Solution 2

The init blocks are not functions, just remove the private fun part and the parentheses:

internal var background: Drawable
internal var xMark: Drawable

init {
    background = ColorDrawable(Color.RED)
    xMark = ContextCompat.getDrawable(this@Subscriptions_main, R.drawable.delete)
}
Share:
16,573
Daniele
Author by

Daniele

I'm a student in computer science in Rome, Italy. I am interested in programming and technology in general! Check out my new Android App: https://play.google.com/store/apps/details?id=com.dancam.chords&hl=it

Updated on June 09, 2022

Comments

  • Daniele
    Daniele almost 2 years

    I have converted this code from Java to Kotlin using Android Studio 3.0

    internal var background: Drawable
    internal var xMark: Drawable
    
    private fun init() {
        background = ColorDrawable(Color.RED)
        xMark = ContextCompat.getDrawable(this@Subscriptions_main, R.drawable.delete)
    }
    

    On line 1 and 2 I'm getting the error:

    Property must be initialized or be abstract

    even though it is going to be initialized in the init function.

    Is writing:

    internal var background: Drawable? = null
    internal var xMark: Drawable? = null
    

    a viable and efficient solution? Is there any other better way?

    • Héctor
      Héctor over 6 years
      You can use lateinit keyword
    • Daniele
      Daniele over 6 years
      Thanks this worked, write an answer argomenting on that if you want. It's gonna be useful for other users too
    • Héctor
      Héctor over 6 years
      Great, glad to help you ;)
    • Vincent Mimoun-Prat
      Vincent Mimoun-Prat over 6 years
      Don't use lateinit blindly, understand what it does and why it may not be what you want.
    • BakaWaii
      BakaWaii over 6 years
      init() is only a function, you cannot guarantee it is called before the property being accessed.
  • Vincent Mimoun-Prat
    Vincent Mimoun-Prat over 6 years
    This solves the problem ... until the code path changes and variables are accessed before being initialized. We do not have enough code to know if lateinit is appropriate or if initializing in constructor / declaration is better.
  • Héctor
    Héctor over 6 years
    Well, in this case, it works for the OP... but ok, you're right.
  • Dale Wilson
    Dale Wilson over 6 years
    OMG, OMG, Never use FEATURE XYZZY because it has A PITFALL is seldom helpful (there are a few cases of language features that should not actually be used, but they are rare.) lateinit is in the language for a reason. As long as the answer mentions the pitfall (or in this case says "read the docs") it is helpful.