Kotlin object vs companion-object vs package scoped methods
Asked Answered
T

3

14

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

Taliataliaferro answered 24/6, 2016 at 20:10 Comment(2)
Maybe this could be of help { https://mcmap.net/q/156446/-effective-enums-in-kotlin-with-reverse-lookup/2804610 }Mayst
In regards to your last paragraph, I think this answer could help you { https://mcmap.net/q/830016/-how-to-access-static-fields-with-reflect-in-kotlin }Mayst
R
2

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")));
}
Respecting answered 26/6, 2016 at 8:46 Comment(1)
Why not direct call from Color class? println(Color.findById(Color.valueOf("RED")));Nielson
B
10

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.

Bereft answered 24/6, 2016 at 21:37 Comment(0)
G
7

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)
Gramps answered 25/6, 2016 at 11:58 Comment(0)
R
2

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")));
}
Respecting answered 26/6, 2016 at 8:46 Comment(1)
Why not direct call from Color class? println(Color.findById(Color.valueOf("RED")));Nielson

© 2022 - 2024 — McMap. All rights reserved.