Объект Kotlin 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
класса Test$asb
, public final doSomething()I
- Ситуация 2:
Test$Companion
класса Test$Companion
, public final doSomething()I
- Ситуация 3: класс
TestKt
, public final static doSomething()I
Мои вопросы:
-
У меня есть класс enum, и я хочу вернуть enum instace с переменной enum, например findById (enum(id, color))
. Как мне это сделать? Сопутствующий объект? объект?
-
Кажется, единственный способ иметь реальный статический метод на уровне пакета, без объявления класса. Но это становится немного слишком глобальным. Есть ли способ получить к нему доступ через: ClassName.staticMethod
, staticMethod действительно статичен.
-
Предоставьте значащие примеры методов объявления пакета, объекта и объекта сопутствующих объектов.
Контекст. Я кодировал в Котлине, и я нахожу это удивительным. Но иногда мне нужно принять решение: например, тяжелое неизменяемое свойство, которое в java я объявляю статичным окончательным, но в Котлине мне трудно "найти эквивалент".
Ответы
Ответ 1
Я бы предложил разработать воддан ответ:
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")));
}
Ответ 2
Если у вас есть функция, которая выполняет некоторые действия, тесно связанные с классом, но не требует экземпляр класса, например, пример findById
, вы должны поместить его в объект-компаньон класса.
Если вы хотите выставить метод как статический метод для Java-кода, вы можете аннотировать его с @JvmStatic
аннотации @JvmStatic
.
Ответ 3
Если функции не требуется экземпляр класса, то это ваше дизайнерское решение, куда его поставить. Используйте уровень пакета, если он специфичен для пакета, используйте компаньона класса, если он близко относится к классу (например, другие классы в пакете имеют схожие функции).
Обратите внимание, что 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)