Kotlin object vs companion-object vs package методы области действия

Я написал эти методы в Котлине и проанализировал байт-код:

Ситуация 1

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

Ситуация 2

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

Ситуация 3

fun doSomething() {}

Результате Байт-Кода

  • Ситуация 1: класс Test$asb, public final doSomething()I
  • Ситуация 2: класс Test$Companion, public final doSomething()I
  • Ситуация 3: класс TestKt, public final static doSomething()I

мои вопросы являются:

  • у меня есть класс перечисления, и я хочу вернуть перечисление instace с учетом переменной перечисления, например, findById (enum(id, color)). Как мне это сделать? Сопутствующий Объект? объект?

  • кажется, единственный способ иметь реальный статический метод на уровне пакета, без объявления класса. Но это становится слишком глобальным. Есть ли способ получить к нему доступ через: ClassName.staticMethod, staticMethod действительно статический.

  • предоставьте значимые примеры методов объявления пакета, сопутствующего объекта и объекта.

контексте. Я кодировал в Котлине, и я нахожу это потрясающим. Но иногда мне нужно принять решение: например, тяжелое неизменяемое свойство, которое в java я бы объявил статическим окончательным, но в Котлине мне трудно "найти эквивалент".

3 ответов


Я бы предложил развивать voddan ответ:

enum class Color {

    RED,
    BLUE,
    GREEN;


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

и тест

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

Если у вас есть функция, которая выполняет некоторые действия тесно связаны с классом, но не требует экземпляр класса, такие как findById пример, следует поместить его в объект класса.

Если вы хотите предоставить метод как статический метод Java-коду, вы можете аннотировать его с помощью @JvmStatic Примечание.


Если функция не требует экземпляра класса, то это ваше дизайнерское решение, куда ее поместить. Используйте уровень пакета, если он специфичен для пакета, используйте компаньон класса, если он близко relets к классу (например, другие классы в пакете имеют аналогичные функции).

отметим, что enum имеет несколько свойств и шаблонов в сборке:

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)