13
votes

I have written this methods in Kotlin and analysed the bytecode:

Situation 1

class A {
    object b {
        fun doSomething() {}
    }
}

Situation 2

class A {
    companion object b {
        fun doSomething() {}
    }
}

Situation 3

fun doSomething() {}

Bytecode Result

  • Situation 1: class Test$asb, public final doSomething()I
  • Situation 2: class Test$Companion, public final doSomething()I
  • Situation 3: class TestKt, public final static doSomething()I

My questions are:

  • I have an enum class, and I want to return an enum instace given an enum variable, for instance, findById (enum(id, color)). How would I do it? Companion Object? object?

  • It seems the only way to have a real static method is in package level, without class declaration. But that becomes a little bit too global. Is there any way to access it via: ClassName.staticMethod, staticMethod being really static.

  • Provide meaningfull examples of package declaration methods, companion object and object.

Context. I have been coding in Kotlin and I find it amazing. But sometimes I need to make a decision: for example, a heavy immutable property which in java I would declare as static final, but in Kotlin I find it hard to "find an equivalent".

3
Maybe this could be of help { stackoverflow.com/q/37794850/2804610 }EPadronU
In regards to your last paragraph, I think this answer could help you { stackoverflow.com/a/37944990/2804610 }EPadronU

3 Answers

2
votes

I would suggest to develop voddan answer:

enum class Color {

    RED,
    BLUE,
    GREEN;


    companion object Utils {
        fun findById(color: Color): Color {
            return color;
        }
    }
}

And to test

@Test
fun testColor() {
    println(Color.Utils.findById(Color.valueOf("RED")));
}
10
votes

If you have a function which performs some action closely related to a class but doesn't require a class instance, such as your findById example, you should put it in the companion object of the class.

If you want to expose a method as a static method to Java code, you can annotate it with the @JvmStatic annotation.

7
votes

If a function does not require an instance of a class, then it is your design decision where to put it. Use package level if it is package-specific, use a class companion if it closely relets to the class (for example other classes in the package have similar functions).

Note that enum has several in-build properties and patterns:

enum class Colour(val value: Int) {
    black(100), red(200), green(300)
}

fun colourById(id: Int) = Colour.values[id]
fun colourByValue(value: Int) = Colour.values.first {it.value == value}
fun colourByName(name: String) = Colour.valueOf(name)