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 только потому что это теперь компилируется, это идея, которая больно аукнется.
Именно это я и подразумевал под фразой "стрельнуть себе в ногу".

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

Комментарии (72)


  1. elusiveavenger
    12.06.2025 12:45

    К динамической типизации var не имеет никакого отношения. Он не "привносит динамики" в java.


    1. dstarakozhev Автор
      12.06.2025 12:45

      "в статически типизированные языки пытаются привнести динамики",
      фраза написана так.
      я не говорю что java становится от наличия var динамически типизированным языком.

      Но этот синтаксический сахар в работу с java привносит одну особенность из динамических языков. Если я объявил переменную, я могу менять ее значение при рефакторинге на любой тип, не меня объявление переменной.
      Либо просто не задумываться о типе переменной при ее создании.

      В java так изначально не было. Подсмотрели это в динамических языках.


      1. aamonster
        12.06.2025 12:45

        Такими темпами у вас Хаскель (у которого статическая типизация настолько строгая, что Яве и не снилось) окажется динамически типизированным языком.


      1. KivApple
        12.06.2025 12:45

        Вы не можете после присваивания var результата функции calculate имеющей тип CalculationResult присвоить ей ничего, кроме другого CalculationResult.

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

        В Java/Kotlin/Scala/Rust/C++ не обязательно (где-то с рождения языка, где-то, как в Java и C++ после обновления стандарта) указывать типы переменных, но переменная имеет тот самый выведенный тип и после того как он выведен, в неё нельзя класть ничего другого.

        Касательно var в Java это вопрос кодстайла. Так же как и фабрика абстрактных фабрик фабрик тоже будет ужасна с точки зрения понимания человека, но Java никак не мешает этому с первой же версии. Всё хорошо в меру.

        Например, var хорошо заходит там, где тип уже упомянут в той же строке, типа каста или new. Нет нужды его дублировать ещё и в описании переменной.


        1. xSVPx
          12.06.2025 12:45

          А какой смысл не дублировать его, если он точно известен? Байты исходников экономить :)?

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


          1. playermet
            12.06.2025 12:45

            Это же Java. Никому не хочется писать что-то вроде InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonPainter в одной строке дважды. Это кстати настоящее имя внутреннего класса из swing.


            1. xSVPx
              12.06.2025 12:45

              Да, но адепты втыкают то var как правило вместо String :).

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


              1. santjagocorkez
                12.06.2025 12:45

                First they were like: перестаньте спрашивать нас на собесах про методы классов стандартной библиотеки, я не хочу учить их наизусть, они есть в справке!

                But then: ты не указал явно имя одного из миллиона классов в иерархии домена, которые я знаю наизусть, как же я теперь узнаю, правильный ли ты выбрал API, бака, дизморалечка тебе!

                Ну вот что тебе даст явное указание имени типа? Допустим, это стандартный тип: идешь и смотришь документацию по нему. Допустим, это новый тип и новый метод, который его возвращает: идешь к месту объявления метода, смотришь тип возврата (а он там всегда явный), далее идёшь к декларации типа, читаешь, возвращаешься к месту вызова метода, продолжаешь читать. Ты в любом случае сначала сбегаешь к декларации типа, явно он указан или через вывод.


          1. KivApple
            12.06.2025 12:45

            Длинные строчки не влезают на экран (особенно в режиме diff). Плюс дублирующаяся информация создаёт визуальный шум. На фоне самоочевидной информации теряется сама бизнес-логика, которую обычно гораздо важнее проверить - с проверкой типов справится и компилятор, а вот корректность алгоритма он не проверит.

            если тип явно не указан - это намекает, что тут не всё так просто, как кажется, и следует изучить как туда что-то ещё попасть может

            Если это Java, то вы знаете, что всё просто и туда может прийти только один, пусть и не указанный явно, тип. Что-то может изменится разве что с обновлением того кода, откуда приходит значение (описание самой функции calculate), но если она что-то радикально другое начнёт возвращать, то скорее всего будет ошибка компиляции (по отсутствию методов или попытки передать в функцию ожидающую конкретный тип, а var для аргументов нельзя). А ещё у вас есть тесты, которые при радикальном изменении поведения возвращаемого значения упадут.

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


    1. assad77
      12.06.2025 12:45

      Если отмести претензии к терминологии, то автор статьи во многом прав. Очень тяжело читать код в котором одни auto или var. Код читается гораздо чаще чем пишется, а чтобы понять что за тип приходится лазить по исходникам.

      А без понимания типа теряется то, ради чего. Ооп и задумывался: Видение предметной области.

      Я думаю авто/var еще более менее оправдан при использовании в функциональном программировании, когда пользуешься длиннющими итераторами с много раз параметризованными шаблонами. Там понимание типа менее важно, но все равно это бонус. Поэтому сам я редко использую слово auto.


  1. mantiscorp
    12.06.2025 12:45

    var result = calculate(args);

    а как насчёт чего-нибудь вроде

    String s = calculate(args).toString()? Тут тоже нет никаких явных типов


    1. dstarakozhev Автор
      12.06.2025 12:45

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

      С появлением var перед разработчиком вариативности как писать стало больше.
      Мое мнение, что писать везде var вместо полноценного типа только потому, что так позволяет компилятор и это короче - не верно.


      1. mantiscorp
        12.06.2025 12:45

        Я говорю о том, что нужно позаботиться о том, чтобы код было удобно читать

        ну, иногда удобне читать var result вместо Optional<Map<String, List<Object>>> result...


        1. dstarakozhev Автор
          12.06.2025 12:45

          все так)
          я и не призываю отказывать от var,

          но если развить этот пример, то альтернативным решением может быть придумать нормальный тип вместо Optional<Map<String, List<Object>>>, что сделает контракт метода не отвратительным, а не просто заметать под var

          вся статья исключительно про эту идею


          1. mantiscorp
            12.06.2025 12:45

            может быть придумать нормальный тип вместо Optional<Map<String, List<Object>>>

            например, class OptionalMapOfStringAndListOfObject extends Optional<Map<String, List<Object>>>?


            1. SimSonic
              12.06.2025 12:45

              Ну всё-таки надо давать имя из доменной модели :) а не отражающее детали реализации :)


          1. panzerfaust
            12.06.2025 12:45

            придумать нормальный тип вместо Optional<Map<String, List<Object>>>, что сделает контракт метода не отвратительным, а не просто заметать под var

            Вся история развития ЯВУ это заметание сложности под половичок. Любая либа или фреймворк заметают под половичок на 100 порядков больше всего, но мешает вам именно вывод типов.


          1. KivApple
            12.06.2025 12:45

            В Java нет алиасов типов.

            Получается, либо велосипедить свой Optional или Map (если по факту нужно вернуть именно это), либо так.


        1. LostFire
          12.06.2025 12:45

          Мне кажется, если так получилось, то проблема уже в архитектуре, но суть понятна.


      1. santjagocorkez
        12.06.2025 12:45

        чтобы код было удобно читать

        Для этого достаточно всего лишь пользоваться IDE вместо редактора для медленных терминалов (vi) или notepad.exe. Навёл мышкой — показало тип.


  1. mirwide
    12.06.2025 12:45

    Называется неявная статическая типизация. В JEP 286: Local-Variable Type Inference есть объяснение зачем. Scala, Kotlin, Go liked this.


    1. dstarakozhev Автор
      12.06.2025 12:45

      У меня нет сомнений, что это нормальная фича.
      Статья про то, что ее нужно использовать осознанно, как и любой другой инструмент.


      1. SimSonic
        12.06.2025 12:45

        Именно статья про то, что это динамическая фича, а вам отвечают, что не динамическая, а неявно статическая. Налицо непонимание теории, бред в статье и отсюда минусы.


  1. eandr_67
    12.06.2025 12:45

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

    var x = 12;
    x = "12345";

    это была бы динамическая типизация.

    Но нет, такое в Java невозможно. И конструкция:

    var x = 12;

    создаёт переменную целого типа, которой можно присваивать только целочисленные значения.

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


    1. dstarakozhev Автор
      12.06.2025 12:45

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


      1. eandr_67
        12.06.2025 12:45

        Вы в своей статье преподносите var как доказательство факта:

        в статически типизированные языки пытаются привнести динамики

        и это не соответствует реальности.

        В var нет динамики. Ни в каком виде нет. Динамика - это когда что-то делается в процессе выполнения кода. Но var работает на этапе компиляции и только компиляции: статика в чистом виде.

        Ваше предположение, что var появился в статически-типизированных языках под влиянием динамически-типизированных, абсолютно ошибочно. Между статическим выводом типов переменных в C#, Go, Java и полным отсутствием типов переменных в JavaScript, Python нет ничего общего.


        1. dstarakozhev Автор
          12.06.2025 12:45

          Спасибо за конструктивный коммент.
          То, что под капотом динамики нет, я осведомлен)
          Видимо фраза "привнести динамики" оказалась слишком абстрактной. Под ней я как раз имел ввиду некоторые заимствования из динамических языков.

          Если я все нашел правильно,
          1. Первый динамический язык LISP появился в 1958 году.
          2. Первый статический язык с выведением типов Meta Language появился в 1973

          Но вот чем именно вдохновлялись разработчики определенных языков, наверняка уже не узнать, к сожалению, или к счастью)


          1. aikuaiven
            12.06.2025 12:45

            1. Первый динамический язык LISP появился в 1958 году.

            Но вот чем именно вдохновлялись разработчики определенных языков

            Язык IPL 1956 и лямбда-исчисление Черча.

            И вообще-то, ANSI Common Lisp 2ed 1991 описывает форму declare с одной из спецификаций - type, указывающей на то, что переменные в связываниях будут принимать значения только указанного типа. И это не делает Common Lisp менее динамически типизированным, а цитируя стандарт: "...носят рекомендательный характер, и могут использоваться Lisp системой для создания дополнительных проверок ошибок или более производительного скомпилированного кода. Декларации также являются хорошим способом задокументировать программу. Следует отметить, что нарушение декларации рассматривается, как ошибка (как, например, для декларации type), но реализация может не замечать этих ошибок (хотя их обнаружение, где это возможно, поощряется)."


          1. CrazyHackGUT
            12.06.2025 12:45

            В C# (Java от Майкрософта, считайте) var уже давно есть, и никто до сих пор не умер.


            1. dadssoip
              12.06.2025 12:45

              В C# даже dynamic есть


      1. KivApple
        12.06.2025 12:45

        Когда это вносили в Java, ссылались на Kotlin/Scala/Go. Все эти языки имеют статическую типизацию с опциональным выводом типов. На Python или JavaScript никто не ссылался.


  1. panzerfaust
    12.06.2025 12:45

    идея, которая больно аукнется

    Так как и где оно аукается? Примеры есть? Не путайте "не знакомо/не привык" с "плохо/мешает/стреляет в ногу".


    1. dstarakozhev Автор
      12.06.2025 12:45

      Но брать и заменять везде явное указание типа на var только потому что это теперь компилируется, это идея, которая больно аукнется

      Предложение звучит полностью так.
      Сам по себе var не плохой. Плохая идея использовать его бездумно везде.
      Как это аукнется:
      Меньше контроля за контрактами. За счет того что типы скрыты, на возникает меньше поводов задуматься о правильности контрактов и композиции.
      В своей практике часто замечал проблемы в коде, именно когда на глаза попадался сомнительный тип переменной в контексте метода.
      + Общее замедление ревью


      1. panzerfaust
        12.06.2025 12:45

        Мне все же кажется, что вы ищете проблемы там, где их нет, чтобы оправдать нежелание принять новый концепт. Самое-то ироничное, что рядом живет котлин, где могут быть огромные функции без единого объявление типов - все чисто на type inference. Я этот код ревьюю каждый день, и может быть в 1 случае из 100 я вижу какой-то сильно накуренный кусок, где явные типы внесли бы ясность. Чаще как раз наоборот: если убрать бесконечные повторения String, Int, JsonObject и т.д, то взгляд меньше спотыкается, и ты читаешь именно идею кода, а не всю эту лапшу. Естественно, вразумительный нейминг обязателен.

        Я еще раз рекомендую вам обдумать идею, что такое "плохо" и что такое "незнакомо".


        1. lavr2004
          12.06.2025 12:45

          Автор статьи прав. Нужны явные типы. Это упрощает код.

          Выведение типов - вот это лапша так лапша... Через полгода-год открываешь свой же код и уже ничего не понимаешь.

          Все эти var и т.п. - ненужная абстракция.


          1. panzerfaust
            12.06.2025 12:45

            Как жаль, что пишущие на Kotlin, Scala и Go не понимают свой код через полгода-год. Наверное, после этого все бросают и переписывают на Java 8.


    1. Artyomcool
      12.06.2025 12:45

      Ну для ознакомления прошло уже достаточно времени, и да, читать код стало сложнее, если var используется где-то за пределами for(var entry : map.entrySet()), т.к. при чтении кода (по крайней мере мне) проще сканить глазами типы, написанные первым словом в строке, понимая сразу все накладываемые на переменную ограничения и особенности поведения, чем надеяться, что автор кода придумал идеальное имя переменной, такое, что при быстром сканировании кода оно не будет вызывать вопросов и вводить в заблуждение.

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

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


      1. KivApple
        12.06.2025 12:45

        Что значит неудачный тип переменной?

        Если тип неудачный, то там и логика пострадает. Что придётся всё с переменной делать через одно место. Условно, искать значение в List перебором вместо выборки из Map.

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

        А если по алгоритму непонятно, что с типами что-то не то, то скорее всего с ними всё то.


        1. Artyomcool
          12.06.2025 12:45

          Я не понял, о каком "неудачном типе" вы говорите, кажется, в моем комментарии такое выражение не встречается.


  1. rsashka
    12.06.2025 12:45

    var в java, это фактически auto в C++


  1. dopusteam
    12.06.2025 12:45

    Тут я сразу вижу что за объект result мне вернулся, и что я могу с ним сделать

    Расскажите, что вы можете сделать с объектом CalculationResult)


    1. 9lLLLepuLLa
      12.06.2025 12:45

      Как минимум перейти по ссылке на него и посмотреть что он из себя представляет.


      1. SimSonic
        12.06.2025 12:45

        Так и по var можно с ctrl щёлкнуть и перейти (вроде бы).


        1. lavr2004
          12.06.2025 12:45

          На самом деле можно не переходить. Если у тебя есть базовый тип IResult и его реализуют классы CalculationResult или ResponseResult, или ещё какой-то Резалт, то ты всё сразу понимаешь...

          А вот если у тебя var, то начинается ненужная возня.


    1. xSVPx
      12.06.2025 12:45

      Какие-то результаты вычислений получить...

      Расскажите, что вы можете сделать с объектом var ?

      Разница. Огромна.


      1. dopusteam
        12.06.2025 12:45

        Вы меняете исходный тезис автора


        1. xSVPx
          12.06.2025 12:45

          Я отвечал вам, а не автору вообще-то. Впрочем в дальнейшей дискуссии смысла совершенно не вижу.

          Фигачьте, мнеж лучше, "без работы не останусь"


  1. Sigest
    12.06.2025 12:45

    Var полезная штука, как выше сказали, никакой динамики она ни грамма не дает. Но удобно очень не копипастить огромные конструкции типов, что очень распространено в java. Вы попробуйте объявить переменную типа Record из jooq с дженериковскими скобками в 20 полей. А понять что за переменная перед вами всегда можно наведя на саму переменную курсор, ну если вы не в блокноте кодите конечно. Не понимаю претензии к var.


    1. gsaw
      12.06.2025 12:45

      В intellj есть галочка, если ее установить, то в редакторе будет добавляться тип переменной.

      Я часто пользуюсь var. Меньше писать, компактнее код визуально. Если не обзывать переменную типа var retval =, как это некоторые делают, а писать понятное, что то вроде var calcResult = , то и читать легче. И потом если вдруг поменялся тип возвращаемый функцией, не надо переписывать вызовы.

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


      1. Sigest
        12.06.2025 12:45

        Да, да. В последних редакциях IDEA подсказки о типах и названиях параметров появляются где надо и где не надо. Так что var вообще стал незаметным на фоне всего этого


      1. AlekseyShibayev
        12.06.2025 12:45

        На ревью приходится разгадывать кроссворды. Не делайте так, пожалуйста.


  1. tenzink
    12.06.2025 12:45

    Прямо вспоминились обсуждения, когда добавлении auto в C++. И ничего - всё устаканилось.


    1. firehacker
      12.06.2025 12:45

      Людям свойственно смиряться с проблемой, побухтев некоторое время. Это не значит, что проблема решена.


      1. tenzink
        12.06.2025 12:45

        Или означает, что проблема была надуманной. Про реальные проблемы плюсов регулярно не забывают писать, но про auto всё тихо

        Не знаю как в java, но в C++, auto не только позволяет писать более чистый код, но и фиксит целый класс ошибок при итерации по ассоциативным контейнерам


    1. Blizzaga
      12.06.2025 12:45

      А какой вой стоял, когда в C# появились анонимные типы и принесли с собой var. Жабий var вроде бы работает аналогично.

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


  1. Pubert
    12.06.2025 12:45

    Дорогие комментаторы

    Автор был не очень точен в формулировке. Безусловно, он имел ввиду "неявную статическую типизацию". Не хейтите его - он понял всё верно)

    Статья, не считая этого косяка, очень даже дельная: не стоит использовать var на каждом шаге. Стоит использовать либо в реально очевидных местах, либо вместо монструозных типовых конструкций, либо в сприптах. Но на самом деле сильно переживать не стоит, ведь обо всём напишут в кодостайле и выскажут на ревью :)


    1. Sigest
      12.06.2025 12:45

      Я сейчас больше работаю с Котлин, чем с Java. В Котлине var и val с самого начала существования языка. И я хочу сказать, что никогда не было проблем с отсутствием типов в коде текста. Никогда не леплю еще и тип в дополнении при объявлении переменной. Хотя в начале плевался на такой подход с непривычки (как и на nullable ?). Но это настолько очищает код, что сейчас считаю это очень хорошей практикой. И в java программирую редко, но делаю то же самое, и очень надеюсь что эта практика скоро будет повсеместной.


    1. dstarakozhev Автор
      12.06.2025 12:45

      Спасибо за поддержку и локализацию ошибки в формулировке)
      Очень приятно, что вы увидели мой посыл и не побоялись словить минус за коммент.

      P.S. большинство оплевух было поделу, но именно ваш коммент вернул мне мотивацию,
      Надеюсь, что следующая статья будет менее противоречивой)


  1. Retropersonality
    12.06.2025 12:45

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


    1. KivApple
      12.06.2025 12:45

      Чтобы не писать MyCoolObject obj = new MyCoolObject(). Или MyCoolObject obj = (MyCoolObject) anotherObject.

      В общем, где тип и так указан в той же строке.

      Ещё может быть какая-то функция (возможно, не ваша вообще, а библиотечная) возвращающая длинный тип из кучи генериков. А тебе из этого типа нужна пара полей.

      Но если подумать о примере автора.

      var result = calculate();

      System.out.println("Elapsed time: " + result.getElapsedTime());

      System.out.println("Result: " + result.getValue());

      А нужно ли мне здесь знать точный тип возврата calculate? Алгоритм то и так понятен (что-то посчитали, вывели инфу о прошедшем времени и значение результата).

      В момент написания кода IDE подскажет какие у него методы. CI/CD уведомит, что код компилируется (если, например, кто-то изменит тип возврата calculate и там больше не будет нужных методов). А на ревью проверяется в первую очередь общая логика.

      В ТЗ был вывод времени и значения. Код выводит время и значение. Готово.


  1. JVyacheslav
    12.06.2025 12:45

    Ну я лично var использую только в двух случаях:

    Когда у меня UsernamePasswordAuthenticationToken в виде типа данных (к примеру, тупо писать много, у меня строка на 100+ символов не учитывая табы получается)

    Либо Map<List<String>, Map<Integer, Pair<String, String>> - к примеру что-то такое (если это ещё и в оптиональ завернуть, вообще опупеешь). P.s. Pair<> в данном случае будет являться кастомным классом.

    Это не выстрел в ногу и не шаг к динамической типизации. Это упрощение жизни разработчикам в таких вот случаях. Под капотом это по факту всё те же типы данных, которые поменять нельзя.


  1. cssru
    12.06.2025 12:45

    var - это очередной жабий сахар. Сахар всегда нужно применять с умом. Если у вас var x = calculateSomething(); то это явно говнокод.

    Но ведь и Something x = calculateSomething(); тоже говнокод.


  1. MonkeyClicker
    12.06.2025 12:45

    Осталось только добавить: вот раньше было лучше. К сожалению, Java сильно устарел из-за свой обратной совместимости, и все фичи давно воспринимаются как запоздалая попытка догнать современные ЯП. Так же Java чересчур многословен, непонятно, зачем нужны лишние слова в языке если они не несут никакой смысловой нагрузки? Scala давно имеет более продвинутую и систему типов, var/val, и еще много чего. Читать код из блокнота/веб страницы - в чем достоинство преодоления трудностей? Это давно обрабатывают IDE/компилятор. Вывод типа - в идее достаточно навести мышь на переменную, не нужно никуда переходить.


  1. man4j
    12.06.2025 12:45

    Почему автор не прогнал статью через гпт? Гпт бы всё автору подробно объяснил бы и возможно даже и нужды в данной статье не было бы.


  1. AlekseyShibayev
    12.06.2025 12:45

    1. Бороться с var бессмысленно. Это факт. Посмотри на количество своих минусов. Единственный способ - тимлид, который запретит использование.

    2. Подсказка в Intelij IDE поможет не сойти с ума. Однако на код ревью, будете и дальше гадать что там за тип.

    3. Если команда адекватная, постарайтесь договориться, о каком-нибудь умном использовании var. Например, только если есть справа new. Или в маленьком приватном методе. Потому что читать простыню кода в перемешку с var и без это гг.

    4. Дженерики, var с ними плохо работает, т.к. кастит к Object. Использование методов возвращающих T, все равно придется писать без var.

    5. var удобен, если тип часто меняется, например был Set, а стал List, не надо трогать тип ссылки.

    6. Если вам не все равно на ваш проект, вы уважаете тех кто читает ваш код, тех кто делает код ревью - не используйте var, или используйте с умом, не создавая дополнительную когнитивную сложность.


  1. vitiok78
    12.06.2025 12:45

    Сразу скажу, я не джавист. И я с большим удивлением узнал, что такая полезная штука, как type inference отсутствовала в Java до появления var.

    Как человек, имеющий богатейший опыт написания кода на языках со строгой типизацией и type inference, могу сказать, что тут исключительно плюсы. Как раз читаемость и понимание кода возрастут крайне сильно, потому что километровые строчки превратятся в элегантные и короткие.

    При этом и компилятор, и IDE вам мгновенно подскажут, если вы что-то не то напишете. Ничего общего с динамической типизацией тут даже близко нет.


  1. playermet
    12.06.2025 12:45

    Запоздалое обсуждение. Синтаксис var появился в Java 10, ему уже 7 лет. Да и вообще его аналог сейчас есть почти в каждом современном статически типизированном языке.


    1. panzerfaust
      12.06.2025 12:45

      Ну так джава-сообщество богато на любителей винтажа. Мягко назовем их так. Где-то вообще до сих пор сидят на Java 8 (2014), а за предложение перейти на Java 11 (2018) могут серьезно оскорбиться.


      1. PlatinumKiller
        12.06.2025 12:45

        А чем вам Java 8 мешает? Работает.. не трогай!


  1. hddn
    12.06.2025 12:45

    Мне вот только непонятно, кто заставляет автора делать кодревью в браузере. Видимо, это происходит под дулом пистолета.


  1. PlatinumKiller
    12.06.2025 12:45

    Гениальный вопрос: зачем? Чтобы в другом месте кода стало больше? Был void чем мешал?


  1. ilja903
    12.06.2025 12:45

    Везде ставлю вар и готов грызть горло каждому кто хочет старые длинные портянки на несколько линий.

    Var не требует импортов, меньше диффов. Больше методов в том же arraylist тк не надо кастить в лист. Портянки с типами теперь короче. Намного более читабельный код, все переменные с 4 буквы начинаются, глазам легко. То что на пуллреквесте не видно типов - это проблема тулзов и это рано или поздно решат. В идее можно сделать чтобы видно было. В плюсах подвезли авто и люди тоже не жалуются. Это лучшая фича жавы со времён восьмерки.