11

Строгая Типизация в Java не всегда спасает в Runtime

Java - это язык строгой типизации. Но это далеко не всегда дает гарантию безопасности во время выполнения программы (т.е. в Runtime).

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

1. Null Pointer Exception - топ-1 проблема в Java.

К сожалению, в Java до сих пор нет null-safe типов. А это значит, что любой объект потенциально может быть не инициализирован и указывать на null. Рассмотрим очевидный случай:"

К сожалению компилятор такое допускает

К сожалению компилятор такое допускает

Решением данной проблемы будет введение null-safe типов, которые будут позволять объекту быть null только если это явно указано.

2.Удаление из коллекции во время итерирования.

Классическая ошибка при работе с коллекциями - удаление записей из коллекции без использования итератора. Рассмотрим пример ниже:

Итерируемся и удаляем одновременно.

Итерируемся и удаляем одновременно.

При попытке запуска такого кода в рантайме мы получим:

Итератор жалуется что кто то модифицировал коллекцию пока он по ней ходил.

Итератор жалуется что кто то модифицировал коллекцию пока он по ней ходил.

Если присмотреться поглубже, можно разглядеть, что внутри итератора это вызывает ошибку при попытке обратиться к следующему элементу:

3. Немодифицируемые коллекции в Java реализуют интерфейсы, предназначенные для модифицируемых коллекций. Аналогичная ситуация существует и для коллекций фиксированного размера.

На мой взгляд, это представляет собой определенный недостаток в дизайне Java. В языке присутствует понятный интерфейс Collection, который устанавливает требования для всех коллекций, включая возможность удаления, добавления и других модификаций данных. Однако существуют реализации, такие как:

  • List<Integer> myNumbers = Arrays.of(1,2,3)

  • List<Integer> myNumbers = Collections.unmodifiableList(new ArrayList<>(mutableNumbers));

  • список можно продолжать

Все эти реализации реализованы через интерфейсы, предполагающие наличие функциональности для модификации данных, но на практике они этого не делают. Об этом становится известно только во время выполнения программы. По вопросу модификаций коллекций, Дуг Ли (Doug Lea) высказывал следующее(см. первый параграф).

Кратко говоря, он не стал разделять существующие коллекции на обычные и немодифицируемые, так как это привело бы к увеличению числа интерфейсов и итераторов: "Now we're up to twenty or so interfaces and five iterators." Создание минимум 20 новых интерфейсов и 5 новых итераторов. Более того это все равно не помогло избежать всех потенциальных Runtime исключений.

Я не могу судить человека, кто написал java.util.concurrent. Но я знаю, что в том же Kotlin'e были созданных Mutable/Immutable коллекции, которые позволяют избежать подобных проблем. Мне не важно, добавит ли Java 25 или 2500 новых классов и надеюсь, что в будущем будут добавлены интерфейсы и реализации, предназначенные исключительно для немодифицируемых коллекций без методов типа get/remove/add и так далее. Все текущие недоразумения могут быть отмечены как устаревшие (deprecated).

4. Перезапуск ранее запущенного потока.

В случае работы с многопоточностью можно допустить ряд ошибок, которые не будут отловлены на моменте компиляции. Например, попытка "переиспользовать" один и тот же поток, запустив его дважды:

Запущенный ранее поток запустить еще раз не выйдет.

Запущенный ранее поток запустить еще раз не выйдет.

5.Некорректная работа с монитором.

Также при работе с монитором нужно соблюдать ряд правил. Я не буду вдаваться в подробности, просто приведу пример неправильной попытки работы с локом:

6.Бесконечная рекурсия.

Компилятор не может отличить рекурсию, которая будет работать с условием прерывания, или без. Поэтому бесконечная рекурсия вполне может быть скомпилирована:

Большинство всех показанных выше проблем отлавливаются утилитами которые анализируют код на ошибки вроде SonarQube или ему подобных, об этом я писал в этой статье.

Спасибо за внимание больше о Java и смежных технологиях я публикую в этом канале.

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества