Утилиты класса в Котлине
В Java мы можем создать класс утилит следующим образом:
final class Utils {
public static boolean foo() {
return false;
}
}
Но как это сделать в Котлине?
Я пытаюсь использовать функции внутри object
:
object Utils {
fun foo(): Boolean {
return false
}
}
Но при вызове этого метода из кода Java к нему нужно добавить INSTANCE
. Пример: Utils.INSTANCE.foo()
.
Затем я изменяюсь, чтобы объявить ее как функцию верхнего уровня (без class
или object
):
@file:JvmName("Utils")
@file:JvmMultifileClass
fun foo(): Boolean {
return true
}
Затем я могу вызвать Utils.foo()
из кода Java. Но из кода Kotlin я получил Unresolved reference
ошибку Unresolved reference
компилятора. Это позволяет только напрямую использовать функцию foo()
(без префикса Utils
).
Итак, каков наилучший подход для объявления класса утилит в Котлине?
Ответы
Ответ 1
Последнее решение, которое вы предложили, на самом деле довольно идиоматично в Kotlin - нет необходимости раскрывать свою функцию во всем, функции верхнего уровня просто удобны для использования в утилитах, фактически, из чего состоит большая часть стандартной библиотеки.
Вы тоже @JvmName
аннотацию @JvmName
, что именно то, как вы должны сделать эти функции верхнего уровня легко вызываемыми для пользователей Java.
Обратите внимание, что вам нужно только @JvmMultifileClass
если вы @JvmMultifileClass
свои функции верхнего уровня в разных файлах, но все же хотите, чтобы они @JvmMultifileClass
в том же файле класса (опять же, только для пользователей Java). Если у вас есть только один файл или вы даете разные имена для каждого файла, вам не нужна эта аннотация.
Если по какой-то причине вам нужен такой же синтаксис Utils.foo()
как в Java, но и в Kotlin, решение с object
а затем @JvmStatic
каждого метода - это способ сделать это, как уже показано в этом ответе @marianosimone.
Ответ 2
Для этого вам нужно использовать @JvmStatic
:
В Котлине:
object Utils {
@JvmStatic
fun foo(): Boolean = true
}
val test = Utils.foo()
В Java:
final boolean test = Utils.foo()
Ответ 3
Обратите внимание, что класс util, который вы использовали в Java, был единственным способом предоставления дополнительных функций там, для всего, что не принадлежало определенному типу или объекту. Использование object
для этого в Котлин не имеет никакого смысла. Это не синглтон, верно?
Второй подход, о котором вы упоминали, скорее всего подходит для использования служебных функций. Внутренне такие функции переходят на статические, и, как вы можете видеть, они становятся статическими классами использования в Java, которые вы ищете, так как вы не можете иметь автономные функции в Java без класса или перечисления. Однако в самом Котлине они являются просто функциями.
Некоторые даже считают классы полезности для анти-шаблонов. С другой стороны, функции имеют смысл без класса или объекта, чье имя не имеет большого значения.