Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 295
johnny_crq Avatar asked Jun 24 '16 20:06

johnny_crq


2 Answers

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.

like image 104
yole Avatar answered Nov 10 '22 03:11

yole


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)
like image 7
voddan Avatar answered Nov 10 '22 01:11

voddan