Я всегда удивлялся, почему Java не делает вывод типов, учитывая, что язык такой, какой он есть, и его виртуальная машина очень зрелая. Google Go - это пример языка с превосходным выводом типов, который уменьшает количество набираемых текстов. Есть ли какая-то особая причина того, что эта функция не является частью Java?
44
Ответы:
Технически говоря, Java имеет вывод типов при использовании обобщений. С помощью общего метода, такого как
Компилятор проанализирует и поймет это при написании
String будет возвращен для первого вызова и Integer для второго вызова на основе того, что было введено в качестве аргумента. В результате вы получите правильную проверку во время компиляции. Кроме того, в Java 7 можно получить дополнительные выводы при создании экземпляров обобщенных типов, например
Java достаточно любезен, чтобы заполнить пустые угловые скобки для нас. Теперь, почему Java не поддерживает вывод типов как часть назначения переменных? В какой-то момент был RFE для вывода типа в объявлениях переменных, но это было закрыто как "Не будет исправлено", потому что
Автор, который закрыл это, также отметил, что это просто «не похоже на java», с чем я согласен. Многословие Java может быть и благословением, и проклятием, но оно делает язык таким, какой он есть.
Конечно, этот конкретный RFE не был концом этого разговора. Во время Java 7 эта возможность снова обсуждалась , при этом были созданы некоторые тестовые реализации, в том числе сам Джеймс Гослинг. Опять же, эта функция была в конечном итоге сбита.
С выпуском Java 8 мы теперь получаем вывод типа как часть лямбда-выражений как таковых:
Компилятор Java , может смотреть на метод ,
Collections#sort(List<T>, Comparator<? super T>)
а затем интерфейсComparator#compare(T o1, T o2)
и определить , чтоfirst
иsecond
должно быть ,String
таким образом , позволяя программисту отказаться от того , чтобы пересчитать тип в лямбда - выражении.источник
First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns
- да, если это так,HashMap<String, Integer> map = foo.getMap()
я согласен - в C # я обычно не используюvar
в таких случаях, хотя я мог бы. Но этот аргумент не выдерживает критики, если это такHashMap<String, Integer> map = new HashMap<String, Integer>()
. Это настоящая избыточность, и я не вижу смысла в том, чтобы писать имя типа дважды. И как бы мне здесь пригодилась перекрестная проверка компилятора, я вообще не понимаю.var
в Java.Humans benefit from the redundancy
является реальным ответом на текущий вопрос, потому что каждое оправдание, которое я прочитал, кажется беспричинным, необоснованным и нелепым оправданием от разработчиков Java: и C #, и C ++ имеют особенность, дизайнеры C # и C ++ не менее компетентны, чем Java, и все счастливы, используя его. Что может отличить разработчиков Java от разработчиков на C # или C ++? Поэтому я согласен с @KonradMorawski, «Это то , как вещи делаются здесь» , кажется , снова быть реальным за кадром причина.Ну, во-первых, вывод типа не имеет никакого отношения к зрелости среды выполнения, будь то 30-летний процессор или виртуальная машина, которая настолько нова, что биты все еще блестящие. все дело в компиляторе.
Тем не менее, это разрешено для обобщенных типов, причина, почему это не разрешено для неуниверсальных типов, по-видимому, из-за философии - ничто не мешает дизайнерам добавить его.
Обновление: похоже, что java 10 поддерживает это - http://openjdk.java.net/jeps/286
источник
Насколько я знаю, когда Java была разработана в начале девяностых, вывод типа не был настолько популярен среди основных языков (но это уже была очень хорошо известная концепция, например, в ML). Итак, я могу себе представить, что вывод типов, вероятно, не был поддержан, потому что Java была нацелена на программистов, пришедших из C ++, Pascal или других основных языков, у которых этого не было (принцип наименьшего удивления).
Кроме того, одним из принципов разработки Java является явное написание вещей, чтобы гарантировать, что программист и компилятор понимают код одинаково: дублирование информации уменьшает вероятность ошибок. Конечно, может быть дело вкуса, стоит ли вводить еще несколько символов дополнительной безопасности, которую он обеспечивает, но такова была философия проектирования Java: писать вещи явно.
Я не знаю, получит ли Java вывод типов в будущем, но IMO, что станет большой революцией для языка (как упомянул Гленн Нельсон, это было описано как «не-java-подобный»), и тогда можно было бы также рассмотреть возможность удаления Назовите Java в пользу нового имени.
Если вы хотите использовать язык JVM с выводом типа, вы можете использовать Scala.
источник
Я могу придумать несколько возможных причин. Во-первых, явная типизация является самодокументированием. Java обычно делает это приоритетом над краткостью. Другая причина может быть в случаях, когда тип является несколько двусмысленным. Например, когда тип или любой подтип может удовлетворить процедуру. Допустим, вы хотите использовать List, но кто-то приходит и использует метод, эксклюзивный для ArrayList. JIT выведет ArrayList и продолжит работу, даже если вы захотите скомпилировать ошибку.
источник
Let's say you want to use a List, but someone comes along and uses a method exclusive to ArrayList. The JIT would infer an ArrayList and carry on even if you wanted a compilation error
- Я не понимаю этого немного. Вывод типа происходит в момент создания переменной, а не вызова метода для нее. Не могли бы вы показать пример того, что вы имели в виду?Это противоречит устоявшейся рекомендации объявлять переменные с использованием наиболее общего интерфейса, который будет соответствовать вашим потребностям, и инициализировать их соответствующим классом реализации, как в
Эффективно,
ничего, кроме синтаксического сахара для
Если вы хотите, ваша IDE может создать его из
new ArrayList<String>()
выражения «одним щелчком» (рефакторинг / создание локальной переменной), но помните, что это противоречит рекомендации «использовать интерфейсы».источник