1. Overview

As we know, Java introduced Enums in version 1.5. Enums make handling constants type-safe, less error-prone, and self-documented. Therefore, Kotlin has Enums type too.

In this quick tutorial, we’ll explore how to create a “static” function in Kotlin’s enum class.

2. Introduction to the Problem

First, regarding the terminology of “method” or “function”, in this tutorial, when we talk about Kotlin, we’ll use “function”. “Method” will be used for the Java context.

In Java, we can add static methods to an enum to do some common operations on the enum instances. However, unlike Java, Kotlin doesn’t have the static keyword.

So if we’ve just come from the Java world, we may have a few questions:

  • how to create “static” functions in Kotlin’s Enums?
  • in Kotlin, can we call the “static functions in the same way as we do in Java?
  • furthermore, can these Kotlin “static” functions be invoked in Java? And how?

Next, we’ll resolve these doubts through examples.

For simplicity, we’ll use unit test assertions to verify if the function invocation returns the expected result.

3. Creating “static” Functions in the companion object

First of all, let’s see an example of a Kotlin enum class:

enum class MagicNumber(val value: Int) {
    ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6),
}

As the code above shows, the MagicNumber enum class has a constructor and a few predefined instances.

We can add functions to a companion object to make them work as “static” functions. This is because the properties and functions within the companion object can be accessed with the class name, such as ClassName.functionName().

So, next, let’s add two “static” functions to the MagicNumber enum class:

enum class MagicNumber(val value: Int) {
    ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6);

    companion object {

        fun pickOneRandomly(): MagicNumber {
            return values().random()
        }

        fun greaterThan(n: Int): List<MagicNumber> {
            return values().filter { it.value > n }
        }
    }
}

As we’ve seen, we’ve created two simple functions in the companion object body.

It’s worth mentioning that if we have more objects or functions after the enum instance block, a semicolon “*;*” is required after the last enum instance. So in our example, it’s “*SIX(6);*“.

Now, let’s create a test to see how the functions are called:

assertNotNull(MagicNumber.pickOneRandomly())
assertEquals(listOf(THREE, FOUR, FIVE, SIX), MagicNumber.greaterThan(2))

The test passes when we run it. So the functions work as expected.

As the code above shows, since the functions are defined within the companion object, we can call them the same way as calling static methods in Java.

Next, let’s see how to call them from Java.

4. Calling Kotlin’s “static” Functions From Java

The functions in Kotlin enum’s companion object can be called in Java through ClassName.Companion.functionName(), for example, MagicNumber.Companion.pickOneRandomly().

However, we can add the @JvmStatic annotation to functions within the companion object body so that Kotlin will generate additional static methods to delegate the corresponding Companion.functions in the compiled bytecode. Then, we can call them as normal static methods that we’re familiar with.

For the sake of demonstration, we’ll add the @JvmStatic annotation only to one function:

enum class MagicNumber(val value: Int) {
    ONE(1), TWO(2), THREE(3) ...

    companion object {
        fun pickOneRandomly(): MagicNumber { ... }

        @JvmStatic
        fun greaterThan(n: Int): List<MagicNumber> { ... }
    }
}

Next, let’s create a test in Java and see how to call the two functions:

// the greaterThan() function with @JvmStatic
assertEquals(Arrays.asList(THREE, FOUR, FIVE, SIX), MagicNumber.greaterThan(2));
                                                                                    
// calling it through the Companion object
assertEquals(Arrays.asList(THREE, FOUR, FIVE, SIX), MagicNumber.Companion.greaterThan(2));
                                                                                    
// the pickOneRandomly() function without @JvmStatic
assertNotNull(MagicNumber.Companion.pickOneRandomly());

The test passes if we give it a run.

As we can see in the Java code above, due to the @JvmStatic annotation, we can invoke the greaterThan() function as a standard Java static method. Further, no matter whether the function has @JvmStatic or not, we can call it through the Companion object in Java.

5. Conclusion

In this article, we’ve addressed how to create a “static” method in Kotlin’s enum class.

Also, we’ve understood the @JvmStatic annotation through examples. Further, we’ve learned how to invoke Kotlin’s “static” methods from Java.

As always, the full source code used in the article can be found over on GitHub.