Одне використання ключового слова 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. variables досі на 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, який - певним чином - дає вам varJava. Це злом, тому застосовуються звичайні відмови від відповідальності, але якщо ви використовуєте 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; він не буде доступний для формалів методів, формалів конструктора, типів повернення методу, полів, формалів спіймання або будь-якого іншого виду змінної декларації.
varJava та 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ім'я класу та використовувати його як таке. Технічно це "контекстне ключове слово" у випадку 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 та її відмінності 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" ;-)