2010-08-09 15 views
212

Jednym ze słów kluczowych var w języku C# jest domyślna deklaracja typu. Jaka jest składnia równoważnika Java dla var?Co to jest odpowiednik słowa kluczowego C# 'var w języku Java?

+4

'val' (lub' var') w przypadku korzystania z konkretnego "zastępczą" język Java ;-) –

+6

@pst: która byłaby Scala? Hm tak, jest. – rsenna

+0

W przypadku IntelliJ przesłałem to jako żądanie funkcji: http://youtrack.jetbrains.com/issue/IDEA-102808 IDE może zwinąć kod, aby pokazać wartość val lub var, nawet jeśli kod źródłowy go nie zawierał. –

Odpowiedz

212

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

Edycja 6 lat po zaksięgowaniu zebrać niektóre z komentarzy poniżej:

  • Powodem C# ma kluczowe var to dlatego, że jest możliwe, aby typy, które nie mają nazwy w .NET. Np:

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

    W tym przypadku byłoby to niemożliwe, aby dać odpowiedni typ do myData. 6 lat temu było to niemożliwe w Javie (wszystkie typy miały nazwy, nawet jeśli były bardzo szczegółowe i niewiarygodne). Nie wiem, czy to się zmieniło w międzyczasie.

  • var to nie to samo co dynamic. var Unieważnienia są nadal w 100% statycznie wpisane. Nie będzie to skompilować:

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

    var currentUser = User.GetCurrent(); 
    

    mogę powiedzieć, że w każdym kodzie, który jestem odpowiedzialny, currentUser ma User lub pochodzącą klasę w nim. Oczywiście, jeśli twoja implementacja User.GetCurrent zwraca int, może to jest dla ciebie szkodliwe.

  • To nie ma nic wspólnego z var, ale jeśli masz dziwne hierarchie dziedziczenia, gdzie cień metody z innymi metodami (np new public void DoAThing()), nie należy zapominać, że metody nie-wirtualnych zależy od rodzaju są oddane jako .

    Nie mogę wyobrazić sobie świat, w którym prawdziwy scenariusz ten jest oznaką dobrego projektu, ale to może nie działać zgodnie z oczekiwaniami:

    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, metody wirtualne nie mają wpływu na to.

  • Nie, nie ma żadnego niezgrabnego sposobu na zainicjowanie 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 staroświecki sposób:

    object foo6; 
    
+1

I być sprawiedliwym także; 1. jest tylko nowością w C#, więc Arturo nie może obwiniać "twórców" i 2. to tylko z powodu innych cech, które nie były w żadnym z tych języków, że jest to pomysł przydatny, a nie wspaniały sposób na uczynienie kodu mniej zrozumiałym i bardziej podatnym na błędy. Jest potrzebny w C# 3.0 i miałby kilka użytecznych przypadków w C# 2.0, ale byłby zły w C# 1.0. –

+1

@Mike Caron: i z powodu pewnych bardzo długich typów (bez 'var', to uczyniłoby Linq praktycznie bezużytecznym). – rsenna

+0

@ pst Co niejawne pisanie ma wspólnego z polimorfizmem? Słowo kluczowe "var" jest w 100% identyczne z deklarowaniem zmiennej z dokładnym typem wyrażenia. To wszystko. –

36

Jeśli dodać Lombok do projektu możesz jej val słów kluczowych.

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

+1

@rightfold: Obiekty, których odniesienia jest "ostateczny" niekoniecznie niezmienny. Rozważmy "final StringBuilder strB = new StringBuilder (" Moje referencje są ostateczne "); strB.append ("Nie jestem niezmienny"); ' –

+1

Od lombok v1.16.12 jest również eksperymentalne wsparcie dla' var'. https://projectlombok.org/features/experimental/var.html –

+0

@MatthiasBraun Twój przykład jest nieprawidłowy. W tym przypadku sama klasa StringBuilder jest niezmienna, po prostu dodajesz wartość łańcucha do swojej wewnętrznej struktury za pomocą metody, jest to całkowicie legalne. –

19

Mam gotowane plugin do IntelliJ że – w sposób – daje var w Javie.To włamanie, więc zwykle obowiązują zrzeczenia, ale jeśli używasz IntelliJ do programowania Java i chcesz go wypróbować, jest to https://bitbucket.org/balpha/varsity.

+0

Byłoby wspaniale mieć skrót klawiaturowy do składania/rozkładania typów deklaracji w bieżącym edytorze. Świetna wtyczka. – hotkey

+2

@hotkey Korzysta z wbudowanego składania kodu IntelliJ, dzięki czemu można rozwinąć wszystko za pomocą Ctrl-Shift-NumPadPlus. Kiedy kursor znajduje się w wierszu zawierającym złożoną deklarację zmiennej, można Ctrl-NumPadPlus i Ctrl-NumPadMinus składać/rozwijać deklaracje w bieżącej metodzie. Składanie wszystkich deklaracji jest nieco niezręczne, złożyłeś wszystko (Ctrl-Shift-NumPadMinus), a następnie wszystko rozłożyłeś (Ctrl-Shift-NumPadPlus). – balpha

7

Prostym rozwiązaniem (zakładając, że korzystasz z przyzwoitego IDE) jest po prostu wpisanie "int" wszędzie, a następnie ustaw go dla siebie.

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

Kod jest nadal zbyt szczegółowy, ale przynajmniej nie trzeba go wpisywać!

+0

Kiedy mówisz "przyzwoity IDE" jest wyłączony Eclipse *? - to nie działa w Lunie (przynajmniej kiedy po prostu wypróbowałem to z 'int') - czy czegoś brakuje? (*: podczas gdy ja nigdy nie nazwałbym Eclipse przyzwoitym IDE, nie mogę osądzać dla innych ...) – BrainSlugs83

+0

@ BrainSlugs83 dunno Używam IDEA, tak naprawdę nie używam wcześniej zaćmienia. Czy to nie poprawia typów dla ciebie? Jestem przyzwyczajony do C#/visual studio/resharper, które jest podobne do IDEA, ale działa właściwie! We wszystkich portach jetbrains możesz nacisnąć alt-enter, aby uzyskać listę sugestii, gdy wystąpi błąd - więc ustawienie typu na int wprowadza błąd, na który możesz wejść i włączyć go, aby posortować typ na –

3

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

5

Możesz odszukać Kotlin od JetBrains, ale jest to val. nie var.

+3

Kotlin ma wartość val i var. val jest równoważny do deklarowania zmiennej końcowej w java, var pozwala na ponowne przypisanie. – samlewis

10

JEP - JDK Enhancement-Wniosek

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

JEP 286: Local-Typ zmiennej Wnioskowanie

Autor Brian Goetz

// Goals: 
var list = new ArrayList<String>(); // infers ArrayList<String> 
var stream = list.stream();   // infers Stream<String> 
+0

Jaką wersję Java? 10? –

+1

Powiązane uwagi: [Pierwszy kontakt z "var" w Javie 10] (https://blog.codefx.org/java/java-10-var-type-inference/) –

2

Lombok supports var ale nadal 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); 

Here to pułapka, której należy unikać, próbując go użyć w wersji IntelliJ IDEA. Wygląda na to, że działa zgodnie z oczekiwaniami, w tym automatyczne uzupełnianie i wszystko. Dopóki nie pojawi się "nie-hacky" rozwiązanie (np. Z powodu JEP 286: Local-Variable Type Inference), to może być teraz najlepszym rozwiązaniem.

Należy pamiętać, że val obsługuje również Lombok bez modyfikowania ani tworzenia lombok.config.

0

Będzie obsługiwany w JDK 10. Można nawet zobaczyć go w akcji w urządzeniu early access build.

JEP 286:

Zwiększenie języka Java rozszerzyć rodzaj wnioskowania do deklaracji zmiennych lokalnych z inicjalizatorów.

Więc teraz zamiast pisać:

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

Piszesz:

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

Uwagi:

  • var jest obecnie zastrzeżony kluczowe
  • Java jest nadal zobowiązanie do pisania statycznego!
  • Może być stosowany tylko w lokalnych deklaracji zmiennych
Powiązane problemy