“Static constants” in Kotlin

Kotlin is designed so that there’s no such thing as a “static member” in a class. If you have a function in a class, it can only be called on instances of this class. If you need something that is not attached to an instance of any class, you define it in a package, outside any class (we call it package-level functions):

But sometimes you need static constants in your class: for example, to comply with requirements of some framework or to use serialization. How do you do this in Kotlin? There are two things in Kotlin that resemble Java’s statics: aforementioned package-level functions and class objects. I’ll explain briefly what class objects are and then proceed to static constants.

Class Objects

A class (not inner and not local) or trait may declare at most one class object associated with it. For example:

Here we have a class, Foo, that declares a class object, which in turn has a member property bar. This means that we can call bar directly on a class name (just like in Java):

Note that we can not call bar on an instance of Foo:

That’s because bar is not a member of Foo, only of its class object. Class object is a separate entity associated with the class, and does not share members with its instances. Neither can we call baz on the class name:

This is because baz is a member of Foo, not of its class object, so you can only call baz on instances of Foo.

Now, let’s look at how class objects work. First, there’s a separate JVM class generated for a class object, and bar is a member of that class. If you access class objects from Java, you have to say something like this:

Class object is an instance stored in a static field inside the class it is defined in, and its properties are accessed with getters/setters.

Static Constants

A property in a class object works as well as a static field (and even better), but only in Kotlin. As we saw above, for Java it looks different, and this may cause problems if some framework or convention (in Java) requires you to have a real static field.

Disclaimer: in Kotlin M5.3 there’s no way to have a static field in your class. It was implemented very recently, so you have it only in the latest nightly build.

When you define a public or internal property in your class object, and do not specify custom getter, nor setter, Kotlin automatically stores it directly in the enclosing class, so that in Java you can say

There’s no difference for your Kotlin code: everything works as it should. Even in Java the old-fashioned Foo.object$.getBar(), but now you can also have real static constants in your class.

Enjoy.

About Andrey Breslav

Andrey is the lead language designer working on Project Kotlin at JetBrains. He also works on making the Java language better, serving as a Java Community Process expert in a group for JSR-335 ("Project Lambda"), and occasionally speak at software conferences such as Devoxx or JavaOne.
This entry was posted in General, Language design and tagged . Bookmark the permalink.

7 Responses to “Static constants” in Kotlin

  1. Peter Niederwieser says:

    What about static methods? There are quite a few Java frameworks that require declaration of static methods. JUnit is one example (@BeforeClass/@AfterClass method), but there are others.

    • Static methods are harder. Looks like we’ll need a workaround test runner to use class-level initializations in JUnit 4 in Kotlin

      • Peter Niederwieser says:

        I’m not worried about JUnit (or Play Framework) in particular. I just wanted to point out that for a pragmatic industrial-strength language designed with excellent Java compatibility in mind, not being able to declare static methods seems like a rather big omission. That said, I don’t know what’s holding you back. Keep up the good work!

  2. Paul says:

    What about Serializable? It forces us to have static final serialversionuid. How can we implement it in Kotlin?

  3. Is it me or does this seem like to much ceremony just to create a constant?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">