johnny_crq
johnny_crq

Reputation: 4391

Kotlin object vs companion-object vs package scoped methods

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

My questions are:

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".

Upvotes: 15

Views: 4621

Answers (3)

Aleosha
Aleosha

Reputation: 151

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")));
}

Upvotes: 2

voddan
voddan

Reputation: 33769

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)

Upvotes: 7

yole
yole

Reputation: 97148

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.

Upvotes: 10

Related Questions