От Java String[] до Kotlin: полный гайд для новичков

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему этот вопрос мучает каждого, кто переходит с Java на Kotlin

Вы только начали изучать Kotlin после Java и уже столкнулись с первой неожиданностью? Вы пытаетесь объявить массив строк так, как привыкли в Java — String[] names = {"Alice", "Bob"} — а компилятор Kotlin выдаёт ошибку? Поздравляю, вы не одиноки. Вопрос "What's the Kotlin equivalent of Java's String[]?" собрал тысячи просмотров на Stack Overflow, и это не случайно.

Kotlin — это не просто «Java с сахаром». Google позиционирует его как более современный, безопасный и лаконичный язык. Но эта лаконичность иногда сбивает с толку новичков. В Java массив — это встроенная конструкция языка. В Kotlin же массивы — это часть стандартной библиотеки, и у них есть свои хитрости.

В этой статье мы разберём всё, что нужно знать о Kotlin массивах строк. Вы узнаете не только прямой аналог String[], но и более гибкие альтернативы, которые сделают ваш код чище и безопаснее. Поехали!

1. Прямой аналог: Array<String>

Самый простой и очевидный способ заменить String[] в Kotlin — это использовать Array<String>. В Kotlin все массивы являются объектами класса Array<T>, где T — тип элементов.

Как объявить и инициализировать?

В Java вы пишете:

String[] names = new String[3];
names[0] = "Alice";
names[1] = "Bob";
names[2] = "Charlie";

В Kotlin это выглядит так:

val names: Array<String> = arrayOfNulls(3)
names[0] = "Alice"
names[1] = "Bob"
names[2] = "Charlie"

Но есть способ гораздо короче — использовать функцию arrayOf():

val names = arrayOf("Alice", "Bob", "Charlie")

Компилятор Kotlin сам выведет тип Array<String>. Обратите внимание: в отличие от Java, в Kotlin нет оператора new для создания массивов. Вместо этого используются фабричные функции.

Важное отличие: фиксированный размер

Как и в Java, размер Array<String> фиксирован. Вы не можете добавить новый элемент после создания. Если попытаетесь обратиться к индексу за пределами длины, получите ArrayIndexOutOfBoundsException.

val fruits = arrayOf("Apple", "Banana")
// fruits[2] = "Cherry" // Ошибка! Индекс выходит за границы

2. Специализированные массивы: не всегда Array<String>

Для примитивных типов (Int, Double, Boolean) Kotlin предлагает оптимизированные классы: IntArray, DoubleArray, BooleanArray и т.д. Они не используют автоупаковку (boxing/unboxing), что экономит память и ускоряет выполнение.

Но для строк такой оптимизации нет, потому что String — это ссылочный тип, а не примитив. Поэтому Array<String> — это единственная опция, если вам нужен именно массив.

3. Альтернатива №1: List<String> (неизменяемый список)

В большинстве случаев вам не нужен массив. В Kotlin настоятельно рекомендуется использовать списки вместо массивов, если вы не работаете с низкоуровневым кодом (например, JNI или оптимизация производительности на уровне наносекунд).

Список List<String> — это неизменяемая коллекция. Вы не можете изменить её размер или элементы после создания. Это делает код безопаснее в многопоточной среде.

val namesList: List<String> = listOf("Alice", "Bob", "Charlie")
// namesList[0] = "Eve" // Ошибка! listOf возвращает неизменяемый список

По сути, listOf — это Kotlin эквивалент Java String[] с дополнительной защитой. В Java массив можно случайно изменить, передав его в другой метод. В Kotlin List этого не позволяет.

4. Альтернатива №2: MutableList<String> (изменяемый список)

Если вам нужна динамическая коллекция, к которой можно добавлять или удалять элементы, используйте MutableList<String>.

val mutableNames = mutableListOf("Alice", "Bob")
mutableNames.add("Charlie")   // Добавляем элемент
mutableNames.removeAt(0)      // Удаляем по индексу
println(mutableNames)         // Вывод: [Bob, Charlie]

Это аналог ArrayList<String> в Java, но в Kotlin он короче и удобнее. mutableListOf() по умолчанию создаёт именно ArrayList.

5. Специальный случай: vararg (переменное количество аргументов)

Иногда в Java вы пишете метод, который принимает String... (varargs). В Kotlin это тоже поддерживается, но с небольшим синтаксическим отличием.

Java:

public void printNames(String... names) {
    for (String name : names) {
        System.out.println(name);
    }
}

Kotlin:

fun printNames(vararg names: String) {
    for (name in names) {
        println(name)
    }
}

// Вызов:
printNames("Alice", "Bob", "Charlie")

Внутри функции names ведёт себя как Array<String>. Вы даже можете передать существующий массив, используя оператор * (spread operator):

val array = arrayOf("Alice", "Bob")
printNames(*array)

Это очень удобно, когда нужно объединить фиксированный массив с переменным количеством аргументов.

6. Как выбрать: массив, список или mutableList?

Вот простая шпаргалка для начинающих:

  • Нужен точный аналог Java String[] — используйте Array<String> с arrayOf().
  • Нужна неизменяемая коллекция (только чтение) — используйте List<String> с listOf().
  • Нужна динамическая коллекция (добавление/удаление) — используйте MutableList<String> с mutableListOf().
  • Пишете функцию с переменным числом аргументов — используйте vararg.

Золотое правило Kotlin: Если не уверены, выбирайте List (неизменяемый). Он безопаснее и более идиоматичен для Kotlin. Массивы (Array) оставьте для случаев, когда вам критична производительность или вы работаете с Java-кодом.

Блоги

Рекомендаций по книгам