Pull to refresh

var в java, так долго ждали, чтобы стрельнуть себе в ногу

Level of difficultyEasy
Reading time4 min
Views13K
UPD

В комментариях справедливо заметили, что я назвал var динамической типизацией вместо выведения типов. Неоспоримо это моя грубая ошибка.

В момент написания статьи не уделил этому достаточно внимания, так как цель статьи была выразить мнение, что явная или неявная типизация это не проблема, с которой нужно бороться, а явление, которое решает определенные задачи если использовать его уместно, и создает проблемы если использовать бездумно

Ни для кого не секрет, что java - это объектно-ориентированный статически-типизированный язык программирования.
Достигается это за счет двух простых принципов

  1. В Java все это объект (и класс, и метод, и поле, и ошибка, и поток, и система, и рантайм)

  2. Все типы необходимо явно прописывать в исходниках и их проверка осуществляется компилятором

Статическая типизация это прекрасно

Сочетание этих двух принципов заставляет нас хорошенечко постараться при написании кода:

  1. Сформировать правильную композицию классов/объектов

  2. Сформировать контракты

  3. Продумать систему типов и их иерархию

  4. Позаботиться обо всех приведениях типов

  5. Позаботиться об обработке исключений и их иерархии

  6. и тд

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

  1. Все загоняется в достаточно узкий стандарт, который понимают все

  2. Большинство проблем отсекается компилятором

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

    public static void main(String[] args) {
        CalculationResult result = calculate(args);
    }

Тут я сразу вижу что за объект result мне вернулся, и что я могу с ним сделать. По большому счету мне даже не важно откуда он взялся и как устроен метод caclulate.
Альтернативой можно использовать динамический тип var

 public static void main(String[] args) {
        var result = calculate(args);
}

В этом случае уже придется понажимать кнопок для того чтобы понять что это за объект в среде разработки и, вероятно, даже провалиться в другой файл. А на код ревью, когда мы смотрим это в браузере такой роскоши нет.
Таким образом секундная экономия времени для разработчика пишущего код превращается в минутное приключение для каждого разработчика, который читает этот код при каждом прочтении + необходимость держать это в голове.
А если мы возьмем совсем динамические языки типа pyton, groovy или JS, то там просмотром сигнатуры метода не ограничится, придется листать реализацию метода до конца, потому что и в возвращаемом значении будет def/var.

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

Зачем же тогда нужно скрывать типы?

Не энтерпрайзом едины.
Для разных задач свои инструменты и код коду рознь:

  1. Написать скрипт - тут важно не обременять код избыточным контекстом.
    Динамическая типизация здесь более чем оправдана. Вся необходимая статическая мишура будет занимать больше места чем полезная нагрузка и только снизит понятность.

  2. Написать код, исполняемый каким то другим воркером.
    Тут важно абстрагироваться от типов, чтобы воркер не был этим связан, и мог использовать свои внутренние оптимальные механизмы.

  3. Написать движок задач по принципу черного ящика.
    Здесь так же динамическая типизация оправдана, потому что система типов находится на стороне потребителей АПИ, и бороться внутри с типами дело сложное и неблагодарно.

  4. Написать бизнеслогику - тут уже явная типизация становится важной, потому что код должен не только быстро писаться и исполняться, но и читаться как книга (быть сам себе документацией).

  5. Написать прототип за дешево - тут важно максимально ускорить разработку и удешевить проверку гипотезы.

  6. Микросервисы - для небольших проектов, которые разработчик знает наизусть, а новому разработчику разобраться во всем проекте потребуется совсем немного времени, проблема явности не стоит так остро.

Почему большинство этрепрайзов пишется на статически типизированных языках?
Очевидно, потому что для них есть много готовых решений и большое комьюнити.
Но как так вышло?
Ответ: естественный отбор.
Почему у людей 2 ноги? Не потому что это идеальное количество ног, а потому что люди с другим количеством ног справлялись хуже с задачами которые перед ними были.

Динамическая типизация очень мощный инструмент, но по достижении определенного объема кода, поддерживать и развивать его становится слишком сложно, в то время как проекты со статической типизацией жили дольше и оставляли потомства больше в своей нише.

Итог

И если вернуться к названию статьи, то появление var в java (и прочего синтаксического сахара) это великолепно, потому что открыло для нее новые двери и увеличило область ее применения, что ускорит ее развитие, ведь развиваются только востребованные продукты.
Но брать и заменять везде явное указание типа на var только потому что это теперь компилируется, это идея, которая больно аукнется.
Именно это я и подразумевал под фразой "стрельнуть себе в ногу".

Тот факт, что в статически типизированные языки пытаются привнести динамики, а в динамические контроль типов, говорит о том, что золотой крайности нет. Нужно всегда четко понимать что и для чего мы делаем, выбирая подходящие инструменты.

Tags:
Hubs:
-16
Comments77

Articles