Одним из применений ключевого слова var в C # является неявное объявление типа. Каков эквивалентный синтаксис Java для var ?
Одним из применений ключевого слова var в C # является неявное объявление типа. Каков эквивалентный синтаксис Java для var ?
Ответы:
Здесь ничего нет. Увы, вы должны ввести полное имя типа.
Редактировать: 7 лет после публикации, вывод типа для локальных переменных (с var) был добавлен в Java 10.
Изменить: через 6 лет после публикации, чтобы собрать некоторые комментарии ниже:
Причина, по которой C # имеет varключевое слово, заключается в том, что в .NET могут быть типы, которые не имеют имени. Например:
var myData = new { a = 1, b = "2" };
В этом случае было бы невозможно дать правильный тип myData. 6 лет назад это было невозможно в Java (у всех типов были имена, даже если они были чрезвычайно многословны и непривычны). Я не знаю, изменилось ли это в то же время.
varэто не то же самое, что dynamic. varТаблицы все еще на 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
Как указано, на виртуальные методы это не влияет.
Нет, нет неуклюжего способа инициализации a 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;var p = new X(); p.Z()это не то же самое , как SuperX p = new X(); p.Z()для всех X и и SuperX, несмотря на то X : SuperX. С varв статическом типе из pвсегда Xв первом примере выше, но всегда SuperXво втором примере. Тонкое, но важное отличие, о котором нужно знать. Но ваш ответ очень правильный :-)
varне делает код менее понятным. Скорее наоборот на мой взгляд. Зачем, например, писать тип два (или даже три) раза в одной строке, когда вы объявляете и создаете его экземпляр ( RadioButton radioButton = new RadioButton();)? varзаставляет вас думать дважды, когда вы называете свои переменные, потому что это переключает внимание на функциональность, а не на тип (например UserCollection collection = new userRepository.GetUsers();, более естественным образом превращается в var users = userRepository.GetUsers();). Если вы думаете, что varнеясно, это просто потому, что не используется для этого.
varопределенно может сделать понятным код, используемый хорошо, но может также сделать его неясным слишком используемым; как много вариантов форматирования. Баланс зависит от того, насколько вы используете анонимные объекты и дженерики, ни один из которых не существовал в .NET 1.0, что делает его менее полезным в качестве гипотетического ключевого слова в первой версии C♯. Я бы назвал a только RadioButton radioButtonв случае фабричного или вспомогательного метода, где единственное, что значило в кнопке, было то, что она была RadioButton, иначе это безумие с или без var.
varкак и вы, если не больше, но я изменил свое мнение, и, возможно, это так же просто, как вопрос разных мнений, потому что я все еще думаю, что вы не правы, когда вы говорите, что это не имеет значения, сколько вы используете анонимных объектов и обобщений;) Объявление типа чаще всего является просто шумом кода, если вы не можете понять код без него, код, вероятно, неясен в любом случае.
varсам по себе просто просит компилятор вывести тип из присваивания; это синтаксический сахар. Сначала я скептически относился к этому, но я использую это религиозно и еще не сталкивался со временем, когда это вызывало путаницу. Это устраняет избыточность при создании экземпляра и устраняет необходимость проверки типа при обращении к нему. В JAVA 9 нет эквивалента JAVA.
Если вы добавите Lombok в свой проект, вы можете использовать его ключевое слово val .
finalкоторые не обязательно неизменна. Рассмотримfinal StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var. projectlombok.org/features/experimental/var.html
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>
Я подготовил плагин для IntelliJ, который - в некотором роде - дает вам varв Java. Это хак, поэтому применяются обычные заявления об отказе от ответственности, но если вы используете IntelliJ для разработки на Java и хотите попробовать его, он находится по адресу https://bitbucket.org/balpha/varsity .
С выпуском JDK 10 20 марта Java теперь включает varзарезервированное имя типа (не ключевое слово - см. Ниже), как указано в JEP 286 . Для локальных переменных в Java 10 или новее действует следующее:
var map = new HashMap<String, Integer>();
varИмя зарезервированным типа в Java практически идентичен varключевому слову в C # в том , что оба позволяют неявного ввода (см ниже важных различий). varв Java может использоваться только для неявного вывода типов в следующих контекстах (как перечислено в JEP 286: Цели ):
Поэтому var нельзя использовать для полей, возвращаемых типов, имен классов или имен интерфейсов. Его обоснование заключается в том, чтобы устранить необходимость включения длинных имен типов при объявлении и определении локальных переменных, как указано в JEP 286 (автор Брайан Гетц):
Мы стремимся улучшить опыт разработчиков, уменьшая церемонию, связанную с написанием кода Java, и в то же время поддерживая приверженность Java безопасности статических типов, позволяя разработчикам исключать часто ненужное объявление манифеста типов локальных переменных.
var Обзор в JavaСледует отметить, что varэто не ключевое слово в Java, а зарезервированное имя типа. Как указано в JEP 286:
Идентификатор var не является ключевым словом; вместо этого это зарезервированное имя типа. Это означает, что на код, который использует var как переменную, метод или имя пакета, это не повлияет; Это повлияет на код, использующий var в качестве имени класса или интерфейса (но на практике эти имена встречаются редко, поскольку они нарушают обычные соглашения об именах).
Обратите внимание, что поскольку varэто зарезервированное имя типа, а не ключевое слово, оно все равно может использоваться для имен пакетов, имен методов и имен переменных (вместе с его новой ролью вмешательства типа). Например, ниже приведены примеры правильного использования varJava:
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Это одно заметное различие между varC # и Java varзаключается в следующем: может использоваться как имя типа в C #, но не может использоваться как имя класса или имя интерфейса в Java. Согласно документации C # (неявно типизированные локальные переменные) :
Если названный тип
varнаходится в области видимости,varключевое слово будет преобразовано в имя этого типа и не будет рассматриваться как часть неявно типизированного объявления локальной переменной.
Возможность использовать varв качестве имени типа в C # создает некоторую сложность и вводит некоторые сложные правила разрешения, которых varв Java избегают , запрещая varиспользовать имя класса или интерфейса. Для получения информации о сложностях varимен типов в C # см. Ограничения, применяемые к объявлениям переменных с неявным типом . Для получения дополнительной информации об обосновании решения о определении объема для `var в Java, см. JEP 286: Выбор области действия .
varдля полей или возвращаемых типов? Почему важно отметить?
varв Java нельзя использовать для полей или возвращаемых типов. Это важно, потому что это ограничение делает varконтекстно-зависимым, где оно может использоваться только в одних контекстах (локальные переменные), но не в других. Это не обязательно является разницей между Java и C #, что следует отметить, но является важным ограничением в целом при использовании varв Java.
varимя класса и использовать его как таковой. Технически это «ключевое слово context» в случае c #, но в Java кажется, что вы не можете сделать то же самое. Поправьте меня если я ошибаюсь.
varв качестве имени класса или имени интерфейса в Java (что в любом случае не является распространенным), но вы можете использовать его для имен переменных, имен методов и имен пакетов. Например, var var = 1;является допустимым заявление Java , но при попытке объявить класс как public class var {}приводит к ошибке: as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations. Я обновил ответ выше, чтобы более подробно рассказать об обосновании varJava и его различиях с varC #.
Он будет поддерживаться в JDK 10. Его даже можно увидеть в действии в ранней сборке доступа .
СЭП 286 :
Расширение языка Java для расширения вывода типов для объявлений локальных переменных с инициализаторами.
Так что теперь вместо того, чтобы писать:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
Ты пишешь:
var list = new ArrayList<String>();
var stream = myStream();
Ноты:
varтеперь зарезервированное имя типаЕсли вы хотите попробовать его без установки 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 ==> []
var), не эквивалентен. В varпримере listэто тип ArrayList, а не List.
Простое решение (при условии, что вы используете приличную IDE) - просто набрать int везде, а затем заставить его установить тип для вас.
На самом деле я просто добавил класс с именем 'var', поэтому мне не нужно вводить что-то другое.
Код все еще слишком многословен, но, по крайней мере, вам не нужно его печатать!
int) - я что-то упустил? (*: хотя я бы никогда не назвал Eclipse достойной IDE, я не могу судить за других ...)
Java 10 действительно делала вывод типа локальной переменной, так что теперь она varв значительной степени эквивалентна C # one (насколько я знаю).
Он также может выводить не денодугируемые типы (типы, которые не могут быть названы в этом месте программистом; хотя, какие типы не денотируемые, отличается). См., Например, Трюки с varанонимными классами (которые вы никогда не должны использовать на работе) .
Единственное отличие, которое я смог найти, это то, что в C #
В Java 10 varнет допустимого имени типа.
По состоянию на Java 10, эквивалент ... var.
Я знаю, что это старше, но почему бы не создать класс var и создать конструкторы с различными типами, и в зависимости от того, какие конструкторы вызываются, вы получаете var с другим типом. Вы даже можете встроить методы для преобразования одного типа в другой.
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.
Вы можете, в Java 10, но только для локальных переменных, то есть
Ты можешь,
var anum = 10; var aString = "Var";
Но не могу,
var anull = null; // Since the type can't be inferred in this case
Проверьте спецификации для получения дополнительной информации.
varможет использоваться для многих форм неотмечаемых типов, включая типы захвата, типы пересечений и анонимные типы классов. И, начиная с Java 11, его также можно применять к лямбда-параметрам.
В общем, вы можете использовать класс 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);
varслово официально на языке, ваш ответ также относится к старомодному способу.
Эта функция теперь доступна в Java SE 10. Статическая, типобезопасная переменная наконец-то вошла в мир Java :)
источник: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
val(илиvar) если вы используете конкретный язык «замены Java» ;-)