16
package example

class Apple {
    val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
}

Class:

package example

class Store {
     fun buy() {
      val SIZE = Apple.APPLE_SIZE_KEY
    }
}

Error:

'APPLE_SIZE_KEY' has private access in 'example.Apple'

But official documentation describes that if we do not specify any visibility modifier, public is used by default.

Why is above error coming?

Malwinder Singh
  • 6,644
  • 14
  • 65
  • 103

2 Answers2

29

What you are trying to do is accessing a value of a class that has no instance. Here are three solutions:

package example

object Apple {
    val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
}

This way you do not need to instantiate anything because of the way objects work in Kotlin.

You could also just instantiate your class like this:

package example

class Store {
     fun buy() {
      val SIZE = Apple().APPLE_SIZE_KEY
    }
}

In this solution you also have an object of Apple, but Apple is still declared as a class.

The third option is a companion object, which behaves like static variables in Java.

package example

class Apple {
    companion object {
        val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
    }
}
creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
  • 2
    It may help to mention `@JvmStatic` which would enable normal static access (`Apple.APPLE_SIZE_KEY`) from Java code, as opposed to `Apple.Companion.INSTANCE.APPLY_SIZE_KEY`. – Salem Jan 04 '18 at 22:13
9

If you want this to be a class level property instead of an instance level property, you can use a companion object:

class Apple {
    companion object {
        val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
    }
}

fun useAppleKey() {
    println(Apple.APPLE_SIZE_KEY)
}

What you currently have is an instance property, which you could use like this:

fun useInstanceProperty() {
    val apple = Apple()
    println(apple.APPLE_SIZE_KEY)
}
zsmb13
  • 85,752
  • 11
  • 221
  • 226
  • 2
    `const val` could be used since the type is `String`, which avoids generating an unnecessary getter. And of course the type can be inferred by the compiler, so: `const val APPLE_SIZE_KEY = "APPLE_SIZE_KEY"` – Michael Jan 04 '18 at 20:34