Jaki jest odpowiednik słowa kluczowego C# 'var' w Javie?

Jedno użycie słowa kluczowego var W C# jest deklaracją typu implicit. Co jest odpowiednikiem składni języka Java dla var?

Author: Peter Mortensen, 2010-08-09

15 answers

Nie ma żadnego. Niestety, musisz wpisać pełną nazwę typu.

Edit: 7 lat po opublikowaniu w Javie 10 dodano wnioskowanie typu dla zmiennych lokalnych (z var).

[[19]} Edit: 6 lat po opublikowaniu, aby zebrać niektóre komentarze od dołu:
  • Powodem, dla którego C# ma słowo kluczowe var jest to, że możliwe jest posiadanie typów, które nie mają nazwy w .NET. Eg:

    var myData = new { a = 1, b = "2" };
    

    W tym przypadku nie byłoby możliwe podanie odpowiedniego typu do myData. 6 lat temu było to niemożliwe w języku Java(wszystkie typy miały nazwy, nawet jeśli były bardzo gadatliwe i nieprecyzyjne). Nie wiem, czy to się zmieniło w międzyczasie.

  • var to nie to samo co dynamic. variables są nadal w 100% wpisywane statycznie. Nie będzie kompilacji:

    var myString = "foo";
    myString = 3;
    
  • var jest również przydatny, gdy typ jest oczywisty z kontekstu. Na przykład:

    var currentUser = User.GetCurrent();
    

    Mogę powiedzieć, że w każdym kodzie, za który jestem odpowiedzialny, currentUser ma User lub klasa pochodna w nim. Oczywiście, jeśli twoja implementacja User.GetCurrent zwróci int, to może jest to dla ciebie niekorzystne.

  • Nie ma to nic wspólnego z var, ale jeśli masz dziwne hierarchie dziedziczenia, w których zacieniasz metody innymi metodami (np new public void DoAThing()), nie zapominaj, że nie-wirtualne metody mają wpływ na typ, jako który są rzucane.

    Nie wyobrażam sobie prawdziwego scenariusza, w którym wskazuje to na dobry projekt, ale może to nie działać tak, jak ty oczekujemy:

    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
    

    Jak wskazano, nie ma to wpływu na metody wirtualne.

  • Nie, Nie ma niezgrabnego sposobu inicjalizacji var bez rzeczywistej zmiennej.

    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
    

    W tym przypadku, po prostu zrób to w staromodny sposób:

    object foo6;
    
 253
Author: Mike Caron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-04 15:47:24

Jeśli dodasz Lombok do swojego projektu możesz użyć jego słowa kluczowego val .

Http://projectlombok.org/features/val.html

 46
Author: darthtrevino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 12:24:22

JEP - JDK Enhancement-Proposal

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

JEP 286: wnioskowanie typu Local-Variable

Autor Brian Goetz

// Goals:
var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>
 27
Author: blueberry0xff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-24 15:36:44

Przygotowałem wtyczkę dla IntelliJ, która-w pewien sposób-daje var w Javie. Jest to hack, więc stosuje się zwykłe zastrzeżenia, ale jeśli używasz IntelliJ do rozwoju Java i chcesz go wypróbować, to jest w https://bitbucket.org/balpha/varsity .

 20
Author: balpha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-14 18:10:11

Wraz z wydaniem JDK 10 w dniu 20 marca, Java zawiera teraz zarezerwowaną nazwę typu var (nie słowo kluczowe-patrz poniżej), jak określono w JEP 286. W przypadku zmiennych lokalnych w Javie 10 lub wyższej obowiązują następujące wartości:

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

Zastrzeżona nazwa typu var w języku Java jest prawie identyczna ze słowem kluczowym var w języku C# , ponieważ oba pozwalają na niejawne wpisywanie (zobacz poniżej istotne różnice). var w języku Java może być używany tylko do wnioskowania typu implicit w następujących kontekstach (jako wyliczone w JEP 286: cele):

  • zmienne lokalne z inicjalizatorami
  • indeksy w rozszerzonej pętli for
  • lokalni zadeklarowani w tradycyjnej pętli for

Dlatego var nie można użyć dla pól, typów zwrotnych, nazw klas lub nazw interfejsu. Jego uzasadnieniem jest usunięcie potrzeby włączania długich nazw typów przy deklarowaniu i definiowaniu zmiennych lokalnych, jak stwierdzono w JEP 286 (autor Brian Goetz):

[20]}staramy się poprawić doświadczenie deweloperów poprzez zmniejszenie ceremonii związane z pisaniem kodu Java, przy zachowaniu zaangażowania Javy do bezpieczeństwa typu statycznego, pozwalając programistom na uniknięcie często-niepotrzebna deklaracja typów zmiennych lokalnych.

var Scoping w Javie

Należy zauważyć, że var nie jest słowem kluczowym w języku Java, ale raczej zastrzeżoną nazwą typu. Cytat z JEP 286:

The identyfikator var nie jest słowem kluczowym; zamiast tego jest typem zastrzeżonym nazwisko. Oznacza to, że kod, który używa var jako zmiennej, metody lub nie będzie miało to wpływu na nazwę pakietu; kod, który używa var jako klasy lub będzie to miało wpływ na nazwę interfejsu (ale nazwy te są rzadkie w praktyce, ponieważ naruszają zwyczajowe konwencje nazewnicze).

Zauważ, że ponieważ var jest zastrzeżoną nazwą typu, a nie słowem kluczowym, nadal może być używana do nazw pakietów, nazw metod i nazw zmiennych (wraz z jej nowy typ-rola interferencji). Na przykład, poniżej znajdują się wszystkie przykłady poprawnych zastosowań var w Javie:

var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
[[20]}cytat z JEP 286:

Leczenie to byłoby ograniczone do zmiennych lokalnych z inicjalizatory, indeksy w rozszerzonej pętli for oraz lokalnie zadeklarowane w tradycyjna pętla for-loop; nie byłaby dostępna dla formularzy metody, formale konstruktorów, typy zwracanych metod, pola, formale catch lub każdy inny rodzaj zmiennej deklaracja.

Różnice pomiędzy var w Javie i C

Jest to jedna znacząca różnica pomiędzy var w C# i Java zawierają następujące elementy: var mogą być używane jako nazwa typu W C#, ale nie mogą być używane jako nazwa klasy lub nazwa interfejsu w Javie. Zgodnie z dokumentacją C# (domyślnie wpisywane zmienne lokalne):

Jeśli w scope znajduje się Typ o nazwie var, to słowo kluczowe var rozwiąże się do nazwy typu i nie będą traktowane jako część bezwarunkowo wpisany deklaracja zmiennej lokalnej.

Możliwość używania var jako nazwy typu W C# tworzy pewną złożoność i wprowadza pewne skomplikowane reguły rozdzielczości, które są unikane przez var w Javie przez wyłączenie var jako nazwy klasy lub interfejsu. Aby uzyskać informacje na temat złożoności nazw typów var W C#, zobacz ograniczenia mają zastosowanie do niejawnie wpisywanych deklaracji zmiennych. Aby uzyskać więcej informacji na temat uzasadnienia decyzji określającej zakres dla " var w Javie, zobacz JEP 286: wybór zakresu .

 20
Author: Justin Albano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-19 18:20:57

Będzie obsługiwany w JDK 10. Można go nawet zobaczyć w akcji w kompilacji wczesnego dostępu .

The JEP 286:

Rozszerzenie języka Java w celu rozszerzenia wnioskowania typu na deklaracje zmiennych lokalnych z inicjalizatorami.

Więc teraz zamiast pisać:

List<> list = new ArrayList<String>();
Stream<> stream = myStream();

Piszesz:

var list = new ArrayList<String>();
var stream = myStream();

Uwagi:


Jeśli chcesz spróbować bez instalowania Javy w lokalnym systemie, stworzyłem Obraz dokera z zainstalowanym 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 ==> []
 11
Author: Maroun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-30 21:08:50

Prostym rozwiązaniem (zakładając, że używasz przyzwoitego IDE) jest po prostu wpisanie 'int' wszędzie, a następnie ustawienie go dla Ciebie.

Właśnie dodałem klasę o nazwie 'var' , więc nie muszę wpisywać czegoś innego.

Kod jest nadal zbyt gadatliwy, ale przynajmniej nie musisz go wpisywać!

 8
Author: JonnyRaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-07 18:13:20

Od Java 10 odpowiednikiem jest ... var.

 6
Author: Brian Goetz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 12:08:32

Możesz spojrzeć na Kotlin przez JetBrains, ale to val. nie var.

 5
Author: Artiom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-16 05:34:09

Java 10 otrzymała wnioskowanie o typie zmiennej lokalnej, więc teraz mA var, co jest prawie równoważne c# (o ile mi wiadomo).

MoĹźe rĂłwnieĹź wywnioskowaÄ ‡ typy Nie-denotowalne (typy, ktĂłre nie mogĹ ' y byÄ ‡ nazwane w tym miejscu przez programistÄ™; choÄ ‡ ktĂłre typy Nie-denotowalne jest róşne). Zobacz np. triki z var i anonimowe klasy (których nigdy nie powinieneś używać w pracy) .

Jedyną różnicą, jaką znalazłem jest to, że w C#,

Jeśli Typ o nazwie var znajduje się w obszarze, wtedy słowo kluczowe var zostanie rozwiązane na nazwę tego typu i nie będzie traktowane jako część niejawnie wpisanej deklaracji zmiennej lokalnej.

W Javie 10 var nie jest legalną nazwą typu.

 5
Author: Alexey Romanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-14 10:32:35

Wiem, że to jest starsze, ale dlaczego nie stworzyć klasy var i stworzyć konstruktory z różnymi typami i w zależności od tego, jakie konstruktory zostaną wywołane, otrzymasz var z innym typem. Możesz nawet zbudować metody konwersji jednego typu na inny.

 3
Author: Sebastian Zaba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-09 06:02:56

Lombok obsługuje var , ale nadal jest klasyfikowany jako eksperymentalny:

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);

Tutaj jest pułapką, której należy unikać, próbując użyć go w IntelliJ IDEA. Wygląda na to, że działa zgodnie z oczekiwaniami, włączając automatyczne uzupełnianie i wszystko. Dopóki nie pojawi się rozwiązanie "non-hacky" (np. ze względu na JEP 286: local-Variable Type Inference ), to może być teraz najlepszym rozwiązaniem.

Zauważ, że val jest również wspierany przez Lombok bez modyfikowania lub tworzenia lombok.config.

 3
Author: BullyWiiPlaza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-06 12:32:39

Można, w Javie 10, ale tylko dla lokalnych zmiennych, czyli

Możesz,

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

Ale nie mogę,

var anull = null; // Since the type can't be inferred in this case

Aby uzyskać więcej informacji, Sprawdź spec .
 2
Author: Antho Christen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-06 06:52:01

Ogólnie można użyć klasy obiektowej dla dowolnego typu, ale trzeba zrobić Typ casting później!

Eg: -

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);
 0
Author: Aditya Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 12:16:24

Ta funkcja jest teraz dostępna w Java SE 10. Statyczny, bezpieczny dla typu var w końcu trafił do świata Javy:)

Źródło: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html

 -1
Author: Sameer Khanal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 06:18:15