Одне використання ключового слова 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 років тому це було неможливо на Яві (усі типи мали назви, навіть якщо вони були надзвичайно багатослівними та непривабливими). Я не знаю, чи змінилося це середнім часом.
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
Як зазначено, на це не впливають віртуальні методи.
Ні, немає жодного незграбного способу ініціалізації 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♯. Я б назвав лише RadioButton
radioButton
те, що стосується фабричного або допоміжного методу, де єдине, що важливе для кнопки, - це те, що це було RadioButton
, інакше це безумство з чи без var
.
var
як і ви, якщо не більше, але я змінив свою думку, і, можливо, це так просто, як питання різних думок, тому що я все ще думаю, що ви помиляєтесь, коли кажете, що це скільки б ви не використовували анонімні об'єкти та дженерики;) Декларація типу - це найчастіше просто шум коду, якщо ви не можете зрозуміти код, без нього код, ймовірно, не зрозумілий в будь-якому випадку.
var
сам просто просить компілятор вивести тип із призначення; це синтаксичний цукор. Спочатку я скептично ставився до цього, але релігійно використовую його і ще не стикаюся з часом, коли це викликало плутанину. Це знімає надмірність при інстанціюванні та усуває необхідність перевірки типу при посиланні. Немає жодного еквівалента JAVA станом на JAVA 9.
Якщо ви додасте 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 (автор Brian Goetz):
Ми прагнемо покращити досвід розробника, зменшивши церемонію, пов’язану з написанням коду 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 та локальними локальними мережами, оголошеними в традиційному for-loop; він не буде доступний для формалів методів, формалів конструктора, типів повернення методу, полів, формалів спіймання або будь-якого іншого виду змінної декларації.
var
Java та CЦе одна помітна відмінність між var
C # і 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
ім'я класу та використовувати його як таке. Технічно це "контекстне ключове слово" у випадку 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
. Я оновив відповідь вище, щоб детальніше розглянути питання про обґрунтування var
Java та її відмінності var
в C #.
Він буде підтримуватися в 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
, а не a List
.
Просте рішення (якщо припустити, що ви використовуєте гідний IDE) - просто ввести "int" скрізь, а потім отримати його, щоб встановити тип для вас.
Я фактично лише додав клас під назвою "var", тому мені не потрібно вводити щось інше.
Код все ще занадто багатослівний, але принаймні вам не потрібно його вводити!
int
) - я щось пропускаю? (*: поки я ніколи не називатиму Eclipse гідним IDE, я не можу судити про інших ...)
Java 10 отримав локальний висновок змінної типу, тому тепер він var
є майже еквівалентним C # one (наскільки я знаю).
Крім того , можна зробити висновок , НЕ denotable типів (типи , які не можуть бути названі в тому місці , програміст, хоча , які типу не є denotable різне). Див. Наприклад, Прийоми з 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" ;-)