Что эквивалентно ключевому слову С# 'var' в Java?

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

Ответ 1

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

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

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

    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;
    

Ответ 3

JEP - JDK Enhancement-Предложение

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

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

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

// Goals:
var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

Ответ 4

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

Ответ 5

Он будет поддерживаться в 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
[email protected]:/# 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 ==> []

Ответ 6

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

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

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

Ответ 7

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

Ответ 8

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

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

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

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

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

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

var Область видимости в 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-loop и locals, объявленные в традиционный для цикла; он не будет доступен для форматов методов, конструкторские форматы, типы возвращаемых методов, поля, формы уловов или любое другое объявление переменной.

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

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

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

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

Ответ 9

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

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

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

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

В Java 10 var не является именем юридического типа.

Ответ 10

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

Ответ 11

Lombok поддерживает var, но он по-прежнему классифицируется как экспериментальный:

import lombok.experimental.var;

var number = 1; // Inferred type: int
number = 2; // Legal reassign since var is not final
number = "Hi"; // Compilation error since a string cannot be assigned to an int variable
System.out.println(number);

Здесь - это ошибка, которую следует избегать при попытке использовать ее в IntelliJ IDEA. Похоже, что он работает как ожидается, включая автоматическое завершение и все. До тех пор, пока не будет "не-хакерское" решение (например, из-за JEP 286: Локально-переменный тип вывода), это может быть вашим лучшим выбором прямо сейчас.

Обратите внимание, что val поддерживается также с помощью Lombok без изменения или создания lombok.config.

Ответ 12

С Java 10 эквивалент... var.

Ответ 13

Вы можете в Java 10, но только для переменных Локальный и только для обозначаемых типов, что означает

Вы можете,

var anum = 10; var aString = "Var";

Но не может,

var anull = null; var aObj = new Object {}; // Anonymous Class

Обратитесь к spec для получения дополнительной информации.

Ответ 15

В общем, вы можете использовать класс Object для любого типа, но позже вы набираете литье!

например: -

Object object = 12;
    Object object1 = "Aditya";
    Object object2 = 12.12;

    System.out.println(Integer.parseInt(object.toString()) + 2);

    System.out.println(object1.toString() + " Kumar");
    System.out.println(Double.parseDouble(object2.toString()) + 2.12);