Как заменить статические методы из Java на Kotlin? Эквивалент static
Использование companion object — прямой аналог static
В Kotlin ключевое слово static отсутствует, но его роль выполняет companion object — специальный объект-компаньон, объявленный внутри класса. Все методы и свойства внутри него ведут себя как статические: они принадлежат классу, а не экземпляру, и вызываются через имя класса.
Вот как переписать ваш пример с Java на Kotlin идиоматично:
class StringUtils {
companion object {
fun isEmpty(str: String?): Boolean {
return str == null || str.trim().isEmpty()
}
fun capitalize(str: String?): String? {
if (isEmpty(str)) return str
return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase()
}
}
}
// Использование:
fun main() {
println(StringUtils.isEmpty("")) // true
println(StringUtils.capitalize("hello")) // "Hello"
}
Теперь вы можете вызывать методы так же, как в Java — через имя класса. companion object — это синглтон, который создаётся один раз при загрузке класса, и все его члены доступны без создания экземпляра.
Дополнительные возможности companion object
- Именование: Вы можете дать companion object имя, чтобы обращаться к нему явно:
companion object Factory { ... }. Тогда вызов будет:StringUtils.Factory.create(). - Константы: Внутри companion object удобно объявлять статические константы с помощью
const val(только для примитивов и строк):
class Config {
companion object {
const val MAX_RETRIES = 3
const val DEFAULT_URL = "https://api.example.com"
}
}
println(Config.MAX_RETRIES)
Альтернатива: функции верхнего уровня (top-level functions)
Если ваш класс не содержит состояния и используется только как набор утилит, лучшим решением будет отказаться от класса вообще и объявить функции на уровне пакета (top-level). Это более идиоматично для Kotlin и избавляет от лишней обёртки:
// StringUtils.kt — файл, не содержащий объявления класса
fun isEmpty(str: String?): Boolean {
return str == null || str.trim().isEmpty()
}
fun capitalize(str: String?): String? {
if (isEmpty(str)) return str
return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase()
}
// Использование:
fun main() {
println(isEmpty(" ")) // true
println(capitalize("kotlin")) // "Kotlin"
}
Такие функции можно вызывать без префикса класса, как глобальные. Они компилируются в статические методы Java-класса с именем файла (например, StringUtilsKt.isEmpty()), но в Kotlin это выглядит естественно.
Важные нюансы
- Аннотация @JvmStatic: Если вы пишете код, который будет вызываться из Java, добавьте
@JvmStaticперед методом в companion object. Иначе из Java придётся писатьStringUtils.Companion.isEmpty(). - Наследование: Методы в companion object не переопределяются в подклассах — они не виртуальные, как и статические методы в Java.
- Расширения: Вы можете добавлять функции-расширения к companion object, что позволяет расширять статические API сторонних классов.
Итог: для прямого аналога static используйте companion object. Для чистых утилит без состояния — top-level функции. Выбор зависит от контекста и необходимости группировки.
Использование object-объявлений (синглтоны)
Ещё один способ организовать статические методы — использовать object. Это объявление создаёт синглтон, все члены которого доступны без создания экземпляра. Он подходит, когда вам нужен не просто набор функций, а объект с состоянием:
object StringUtils {
private val cache = mutableMapOf<String, String>()
fun capitalize(str: String?): String? {
if (str == null) return null
return cache.getOrPut(str) {
str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase()
}
}
}
// Использование:
fun main() {
println(StringUtils.capitalize("hello")) // "Hello"
}
В отличие от companion object, object не привязан к внешнему классу — это самостоятельная сущность. Он инициализируется лениво при первом обращении и может реализовывать интерфейсы или наследоваться от классов. Это удобно для фабрик или реестров.
Если же вам нужно совместить статические методы с экземплярными, используйте companion object. Если нужен чистый синглтон без внешнего класса — object будет лучшим выбором.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги