Что эквивалентно ключевому слову С# '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;
Ответ 2
Если вы добавите Lombok в свой проект, вы можете использовать его ключевое слово val.
http://projectlombok.org/features/val.html
Ответ 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 для получения дополнительной информации.
Ответ 14
Эта функция теперь доступна в Java SE 10. Статический, безопасный тип var, наконец, попал в java-мир:)
источник: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
Ответ 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);