What is the equivalent of Java static final fields in Kotlin?
In Kotlin, you substitute Java's static final with a companion object. The const val construct is used for compile-time constants such as primitives or String, whereas for other types, you'd simply use val.
For Primitive/String:
For Other types:
Access using MyClass.CONSTANT, similar to how static final in Java would be accessed.
Deep dive into Kotlin constants
Comprehensive guide to declaring constants
In Kotlin, you use const val before a primitive or String type to declare a compile-time constant. Note that const val hints the compiler that the value will be a constant expression:
If you need to access this constant throughout your application, define it within a companion object or an object declaration:
Interoperability with Java: @JvmStatic and @JvmField
We love const val but sometimes we need to play nice with Java. This is where @JvmStatic and @JvmField annotations enter the scene. @JvmStatic before a val in a Companion Object exposes it as a static field to Java:
And for a property to be a static field (no getters here!) visible to Java, use @JvmField:
Scope the constants: Within file, Class or globally?
Using const val you can define compile-time constants. However, read-only field that are to be initialized during runtime (and aren't necessarily a compile-time constant) you use private val, and the visibility will be limited to the scope of the file:
Note, const val should be used for primitives and String types. Use it within an object, companion object, or at the top level of a file for global constants.
Naming constants: Uppercase with underscores
Just like Java, in Kotlin too constants are often defined in uppercase letters with underscores separating different words:
Uppercase naming differentiates compile-time constants from mutable variables or read-only values:
Advanced usage of Kotlin constants
Best practices: When and how to use constants
If you're dealing with true constants that are known and can't change at compile-time, use const val:
For values that need to be computed at runtime but will remain constant thereafter, use val:
Lastly, always group your constants logically using objects or companion objects. This way you provide order and improve readability.
Potential pitfalls to avoid
Here are some common issues that may arise:
- Erroneous references: Make sure to access constants statically -
ClassName.CONSTANT, and not through instance references. - Initialization order: Keep initialization order in mind when dealing with companion objects.
- Java interoperability: Don't forget to use
@JvmStaticor@JvmFieldwhen Kotlin properties need to be accessed asstaticfrom Java.
Was this article helpful?