Что эквивалентно ключевому слову C # 'var' в Java? - PullRequest
251 голосов
/ 10 августа 2010

Одно использование ключевого слова var в C # - неявное объявление типа. Каков эквивалентный синтаксис Java для var ?

Ответы [ 15 ]

239 голосов
/ 10 августа 2010

Там нет ни одного.Увы, вам нужно ввести полное имя типа.

Редактировать: через 7 лет после публикации в Java 10 был добавлен вывод типа для локальных переменных (с var).

Редактировать: 6 лет после публикации, чтобы собрать некоторые комментарии ниже:

  • Причина, по которой C # имеет ключевое слово var, заключается в том, что возможно иметь типы без имени.СЕТЬ.Например:

    var myData = new { a = 1, b = "2" };
    

    В этом случае было бы невозможно дать правильный тип для myData.6 лет назад это было невозможно в Java (у всех типов были имена, даже если они были чрезвычайно многословны и непривычны).Я не знаю, изменилось ли это в это время.

  • var - это не то же самое, что dynamic.var iables по-прежнему на 100% статически типизированы.Это не скомпилирует:

    var myString = "foo";
    myString = 3;
    
  • var также полезно, когда тип очевиден из контекста.Например:

    var currentUser = User.GetCurrent();
    

    Я могу сказать, что в любом коде, за который я отвечаю, currentUser имеет User или производный класс.Очевидно, что если ваша реализация User.GetCurrent вернет int, то, возможно, это ущерб вам.

  • Это не имеет ничего общего с var, но если у вас странное наследованиеИерархии, где вы скрываете методы другими методами (например, new public void DoAThing()), не забывайте, что на не виртуальные методы влияет Тип, к которому они приводятся.

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

    class Foo {
        public void Non() {}
        public virtual void Virt() {}
    }
    
    class Bar : Foo {
        public new void Non() {}
        public override void Virt() {}
    }
    
    class Baz {
        public static Foo GetFoo() {
            return new Bar();
        }
    }
    
    var foo = Baz.GetFoo();
    foo.Non();  // <- Foo.Non, not Bar.Non
    foo.Virt(); // <- Bar.Virt
    
    var bar = (Bar)foo;
    bar.Non();  // <- Bar.Non, not Foo.Non
    bar.Virt(); // <- Still Bar.Virt
    

    Как указано, это не влияет на виртуальные методы.

  • Нет,нет неуклюжего способа инициализации var без фактической переменной.

    var foo1 = "bar";        //good
    var foo2;                //bad, what type?
    var foo3 = null;         //bad, null doesn't have a type
    var foo4 = default(var); //what?
    var foo5 = (object)null; //legal, but go home, you're drunk
    

    В этом случае просто сделайте это по старинке:

    object foo6;
    
43 голосов
/ 14 декабря 2010

Если вы добавите Lombok в свой проект, вы можете использовать его ключевое слово val .

http://projectlombok.org/features/val.html

26 голосов
/ 24 июля 2017

JEP - Предложение по расширению JDK

http://openjdk.java.net/jeps/286

JEP 286: вывод типа локальной переменной

Автор Брайан Гетц

// Goals:
var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>
20 голосов
/ 14 апреля 2013

Я подготовил плагин для IntelliJ, который - в некотором роде - дает вам var в Java.Это хак, поэтому применяются обычные заявления об отказе от ответственности, но если вы используете IntelliJ для разработки на Java и хотите попробовать его, он стоит https://bitbucket.org/balpha/varsity.

13 голосов
/ 01 апреля 2018

С выпуском JDK 10 20 марта Java теперь включает в себя var имя зарезервированного типа (не ключевое слово - см. Ниже), как указано в JEP 286 . Для локальных переменных в Java 10 или новее действует следующее:

var map = new HashMap<String, Integer>();

Имя зарезервированного типа var в Java почти идентично ключевому слову var в C #, поскольку оба допускают неявную типизацию (важные различия см. Ниже). var в Java может использоваться только для неявного вывода типов в следующих контекстах (как перечислено в JEP 286: Цели ):

  • локальные переменные с инициализаторами
  • индексы в расширенном цикле for
  • местные жители, объявленные в традиционном цикле for

Поэтому var нельзя использовать для полей, типов возвращаемых данных, имен классов или имен интерфейсов. Его обоснование состоит в том, чтобы исключить необходимость включения длинных имен типов при объявлении и определении локальных переменных, как указано в JEP 286 (автор Brian Goetz):

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

var Scoping in Java

Следует отметить, что var - это не ключевое слово в Java, а зарезервированное имя типа. Как указано в JEP 286:

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

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

var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;

Как указано в JEP 286:

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

Различия между var в Java и C #

Это одно заметное различие между var в C # и Java заключается в следующем: var может использоваться в качестве имени типа в C #, но не может использоваться в качестве имени класса или имени интерфейса в Java. Согласно документации C # (неявно типизированные локальные переменные) :

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

Возможность использовать var в качестве имени типа в C # создает некоторую сложность и вводит некоторые сложные правила разрешения, которых var в Java избегает, запрещая var в качестве имени класса или интерфейса. Для получения информации о сложностях var имен типов в C # см. Ограничения применяются к объявлениям переменных с неявным типом . Для получения дополнительной информации об обосновании решения о определении объема для `var в Java см. JEP 286: Выбор области действия .

11 голосов
/ 22 февраля 2018

Он будет поддерживаться в JDK 10. Его даже можно увидеть в действии в ранней сборке с доступом .

JEP 286 :

Расширение языка Java для расширения вывода типов для объявлений локальных переменных с инициализаторами.

Так что теперь вместо того, чтобы писать:

List<> list = new ArrayList<String>();
Stream<> stream = myStream();

Вы пишете:

var list = new ArrayList<String>();
var stream = myStream();

Примечания:

  • var теперь зарезервированное имя типа
  • Java - это все еще приверженность статической типизации!
  • Может использоваться только в локальных объявлениях переменных

Если вы хотите попробовать его без установки Java в вашей локальной системе, я создал образ Docker с установленным JDK 10:

$ docker run -it marounbassam/ubuntu-java10 bash
root@299d86f1c39a:/# jdk-10/bin/jshell
Mar 30, 2018 9:07:07 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
|  Welcome to JShell -- Version 10
|  For an introduction type: /help intro

jshell> var list = new ArrayList<String>();
list ==> []
8 голосов
/ 09 мая 2014

Простое решение (при условии, что вы используете приличную IDE) состоит в том, чтобы просто набрать 'int' везде, а затем заставить его установить тип для вас.

Я на самом деле просто добавил класс с именем 'var', поэтому мне не нужно вводить что-то другое.

Код все еще слишком многословен, но, по крайней мере, вам не нужно его набирать!

5 голосов
/ 29 марта 2018

Java 10 действительно получала вывод типа локальной переменной, поэтому теперь она имеет var, что в значительной степени эквивалентно C # (насколько я знаю).

Она также может выводить недетонируемыетипы (типы, которые не могут быть названы в этом месте программистом; хотя , которые типы не могут быть денотированы, отличается, например, Java не имеет эквивалента анонимных типов C #).

Единственное отличие, которое я могу найти, состоит в том, что в C #

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

В Java 10 var не является допустимым именем типа.

5 голосов
/ 16 августа 2015

Вы можете взглянуть на Kotlin от JetBrains, но это val. не вар.

3 голосов
/ 02 апреля 2018

Начиная с Java 10, эквивалент ... var.

...