Eine Verwendung des Schlüsselworts var in C # ist die implizite Typdeklaration. Was ist die Java-äquivalente Syntax für var ?
Eine Verwendung des Schlüsselworts var in C # ist die implizite Typdeklaration. Was ist die Java-äquivalente Syntax für var ?
Antworten:
Da ist gar nichts. Leider müssen Sie den vollständigen Typnamen eingeben.
Bearbeiten: 7 Jahre nach der Veröffentlichung var
wurde in Java 10 eine Typinferenz für lokale Variablen (mit ) hinzugefügt.
Bearbeiten: 6 Jahre nach dem Posten, um einige der Kommentare von unten zu sammeln:
Der Grund, warum C # das var
Schlüsselwort hat, ist, dass es möglich ist, Typen zu haben, die in .NET keinen Namen haben. Z.B:
var myData = new { a = 1, b = "2" };
In diesem Fall wäre es unmöglich, einen geeigneten Typ anzugeben myData
. Vor 6 Jahren war dies in Java unmöglich (alle Typen hatten Namen, auch wenn sie extrem ausführlich und unfreundlich waren). Ich weiß nicht, ob sich dies inzwischen geändert hat.
var
ist nicht dasselbe wie dynamic
. var
iables sind immer noch zu 100% statisch typisiert. Dies wird nicht kompiliert:
var myString = "foo";
myString = 3;
var
ist auch nützlich, wenn der Typ aus dem Kontext ersichtlich ist. Beispielsweise:
var currentUser = User.GetCurrent();
Ich kann sagen, dass in jedem Code, für den ich verantwortlich bin, currentUser
eine User
oder eine abgeleitete Klasse enthalten ist. Wenn Ihre Implementierung von User.GetCurrent
return an int ist, ist dies möglicherweise ein Nachteil für Sie.
Dies hat nichts damit zu tun var
, aber wenn Sie seltsame Vererbungshierarchien haben, in denen Sie Methoden mit anderen Methoden (z. B. new public void DoAThing()
) beschatten , vergessen Sie nicht, dass nicht virtuelle Methoden von dem Typ betroffen sind, als den sie umgewandelt werden.
Ich kann mir kein reales Szenario vorstellen, in dem dies auf gutes Design hinweist, aber dies funktioniert möglicherweise nicht wie erwartet:
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
Wie bereits erwähnt, sind virtuelle Methoden davon nicht betroffen.
Nein, es gibt keine ungeschickte Möglichkeit, a var
ohne eine tatsächliche Variable zu initialisieren .
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
In diesem Fall machen Sie es einfach auf die altmodische Weise:
object foo6;
var p = new X(); p.Z()
ist nicht dasselbe wie SuperX p = new X(); p.Z()
für alle X und und SuperX, obwohl X : SuperX
. Mit var
dem statischen Typ p
steht immer X
im ersten Beispiel oben, aber immer SuperX
im zweiten Beispiel. Ein subtiler, aber wichtiger Unterschied, den man beachten muss. Aber deine Antwort ist sehr richtig :-)
var
macht den Code nicht weniger klar. Eher das Gegenteil meiner Meinung nach. Warum schreiben Sie den Typ beispielsweise zwei (oder sogar drei) Mal in dieselbe Zeile, wenn Sie ihn deklarieren und instanziieren ( RadioButton radioButton = new RadioButton();
)? var
lässt Sie beim Benennen Ihrer Variablen eher zweimal überlegen, da der Fokus eher auf der Funktionalität als auf dem Typ liegt (zum Beispiel UserCollection collection = new userRepository.GetUsers();
eher natürlich var users = userRepository.GetUsers();
). Wenn Sie denken, var
ist unklar, ist es nur, weil es nicht daran gewöhnt ist.
var
kann definitiv klar machen, dass Code gut verwendet wird, aber es kann auch unklar machen, ob er zu schlecht verwendet wird. wie viele Formatierungsoptionen. Das Gleichgewicht hängt davon ab, wie oft Sie anonyme Objekte und Generika verwenden, von denen keines in .NET 1.0 vorhanden war. Dies macht es als hypothetisches Schlüsselwort in der ersten Version von C♯ weniger nützlich. Ich würde a nur RadioButton
radioButton
im Fall einer Fabrik- oder Hilfsmethode nennen, bei der das einzige, was an dem Knopf von Bedeutung war, war, dass es ein war RadioButton
, sonst ist das Wahnsinn mit oder ohne var
.
var
wie Sie, wenn nicht mehr, aber ich habe meine Meinung geändert, und vielleicht ist es so einfach wie eine Frage unterschiedlicher Meinungen, weil ich immer noch denke, dass Sie falsch liegen, wenn Sie sagen, dass es eine ist egal wie oft Sie anonyme Objekte und Generika verwenden;) Die Typdeklaration ist meistens nur Code-Rauschen. Wenn Sie den Code ohne ihn nicht verstehen können, ist der Code wahrscheinlich in beiden Fällen unklar.
var
selbst fordert den Compiler einfach auf, den Typ aus der Zuweisung abzuleiten; Es ist syntaktischer Zucker. Anfangs war ich skeptisch, aber ich benutze es religiös und habe noch keine Zeit erlebt, in der es Verwirrung stiftete. Es beseitigt Redundanz beim Instanziieren und macht es überflüssig, den Typ beim Referenzieren zu überprüfen. Es gibt kein JAVA-Äquivalent ab JAVA 9.
Wenn Sie Ihrem Projekt Lombok hinzufügen, können Sie dessen Schlüsselwort val verwenden .
final
sind nicht unbedingt unveränderlich. Betrachten Siefinal StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var
. projectlombok.org/features/experimental/var.html
JEP - JDK-Verbesserungsvorschlag
http://openjdk.java.net/jeps/286
JEP 286: Typinferenz lokaler Variablen
Autor Brian Goetz
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
Ich habe ein Plugin für IntelliJ zusammengestellt, das Ihnen var
in gewisser Weise Java bietet . Es ist ein Hack, daher gelten die üblichen Haftungsausschlüsse. Wenn Sie jedoch IntelliJ für Ihre Java-Entwicklung verwenden und es ausprobieren möchten, finden Sie es unter https://bitbucket.org/balpha/varsity .
Mit der Veröffentlichung von JDK 10 am 20. März enthält Java jetzt einen var
reservierten Typnamen (kein Schlüsselwort - siehe unten), wie in JEP 286 angegeben . Für lokale Variablen gilt jetzt Folgendes in Java 10 oder höher:
var map = new HashMap<String, Integer>();
Der var
reservierte Typname in Java ist nahezu identisch mit dem var
Schlüsselwort in C #, da beide eine implizite Typisierung ermöglichen (wichtige Unterschiede siehe unten). var
in Java kann nur für implizite Typinferenz in den folgenden Kontexten verwendet werden (wie in JEP 286 aufgezählt : Ziele ):
Daher var
kann nicht für Felder, Rückgabetypen, Klassennamen oder Schnittstellennamen verwendet werden. Das Grundprinzip besteht darin, die Notwendigkeit zu beseitigen, lange Typnamen in die Deklaration und Definition lokaler Variablen aufzunehmen, wie in JEP 286 (verfasst von Brian Goetz) angegeben:
Wir möchten die Entwicklererfahrung verbessern, indem wir die mit dem Schreiben von Java-Code verbundene Zeremonie reduzieren und gleichzeitig Javas Engagement für die Sicherheit statischer Typen beibehalten, indem wir Entwicklern ermöglichen, die häufig unnötige Manifestdeklaration lokaler Variablentypen zu umgehen.
var
Scoping in JavaEs ist zu beachten, dass dies var
in Java kein Schlüsselwort ist, sondern ein reservierter Typname. Wie aus JEP 286 zitiert:
Der Bezeichner var ist kein Schlüsselwort. Stattdessen ist es ein reservierter Typname. Dies bedeutet, dass Code, der var als Variablen-, Methoden- oder Paketnamen verwendet, nicht betroffen ist. Code, der var als Klassen- oder Schnittstellennamen verwendet, ist betroffen (diese Namen sind jedoch in der Praxis selten, da sie gegen die üblichen Namenskonventionen verstoßen).
Da var
es sich um einen reservierten Typnamen und kein Schlüsselwort handelt, kann er weiterhin für Paketnamen, Methodennamen und Variablennamen verwendet werden (zusammen mit seiner neuen Typinterferenzrolle). Im Folgenden finden Sie beispielsweise alle Beispiele für gültige Verwendungen var
in Java:
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
Wie aus JEP 286 zitiert:
Diese Behandlung würde auf lokale Variablen mit Initialisierern, Indizes in der erweiterten for-Schleife und in einer traditionellen for-Schleife deklarierten Einheimischen beschränkt sein. Es ist nicht verfügbar für Methodenformale, Konstruktorformale, Methodenrückgabetypen, Felder, Catch-Formale oder andere Arten von Variablendeklarationen.
var
in Java & C.Dies ist ein bemerkenswerter Unterschied zwischen var
C # und Java: var
Kann als Typname in C # verwendet werden, kann jedoch nicht als Klassenname oder Schnittstellenname in Java verwendet werden. Gemäß der C # -Dokumentation (implizit typisierte lokale Variablen) :
Wenn sich ein Typ mit dem Namen
var
im Gültigkeitsbereich befindet, wird dasvar
Schlüsselwort in diesen Typnamen aufgelöst und nicht als Teil einer implizit typisierten lokalen Variablendeklaration behandelt.
Die Möglichkeit, var
in C # als Typname zu verwenden, führt zu einer gewissen Komplexität und führt einige komplizierte Auflösungsregeln ein, die var
in Java vermieden werden, indem sie var
als Klassen- oder Schnittstellenname nicht zugelassen werden. Informationen zur Komplexität von var
Typnamen in C # finden Sie unter Einschränkungen für implizit typisierte Variablendeklarationen . Weitere Informationen zu den Gründen für die Scoping-Entscheidung für var in Java finden Sie in JEP 286: Scoping Choices .
var
für Felder oder Rückgabetypen verwenden können? Warum ist es wichtig zu beachten?
var
in Java kann nicht für Felder oder Rückgabetypen verwendet werden. Dies ist wichtig, da diese Einschränkung var
kontextsensitiv ist und nur in einigen Kontexten (lokalen Variablen) und nicht in anderen verwendet werden kann. Dies ist nicht unbedingt ein Unterschied zwischen Java und C #, der beachtet werden sollte, sondern eine wichtige Einschränkung im Allgemeinen bei der Verwendung var
in Java.
var
einen Klassennamen erstellen und als solchen verwenden. Technisch gesehen ist es im Fall von c # ein "Kontextschlüsselwort", aber in Java scheint es, dass Sie nicht dasselbe tun können. Korrigiere mich, wenn ich falsch liege.
var
in Java keinen Klassennamen oder Schnittstellennamen verwenden (was ohnehin nicht üblich ist), aber Sie können ihn für Variablennamen, Methodennamen und Paketnamen verwenden. Beispiel: var var = 1;
Ist eine gültige Java-Anweisung, aber der Versuch, eine Klasse zu deklarieren, public class var {}
führt zu einem Fehler : as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
. Ich habe die Antwort oben aktualisiert, um detaillierter auf die Gründe für var
Java und die Unterschiede zu var
C # einzugehen.
Es wird in JDK 10 unterstützt. Es ist sogar möglich, es im Early Access Build in Aktion zu sehen .
Der JEP 286 :
Erweitern Sie die Java-Sprache, um die Typinferenz auf Deklarationen lokaler Variablen mit Initialisierern zu erweitern.
Also jetzt anstatt zu schreiben:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
Du schreibst:
var list = new ArrayList<String>();
var stream = myStream();
Anmerkungen:
var
ist jetzt ein reservierter TypnameWenn Sie es ausprobieren möchten, ohne Java auf Ihrem lokalen System zu installieren, habe ich ein Docker-Image mit JDK 10 erstellt:
$ 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
) nicht gleichwertig ist. Im var
Beispiel list
ist vom Typ ArrayList
, nicht a List
.
Eine einfache Lösung (vorausgesetzt, Sie verwenden eine anständige IDE) besteht darin, überall "int" einzugeben und dann den Typ für Sie festzulegen.
Ich habe gerade eine Klasse namens 'var' hinzugefügt, damit ich nichts anderes eingeben muss.
Der Code ist immer noch zu ausführlich, aber zumindest müssen Sie ihn nicht eingeben!
int
) - Vermisse ich etwas? (*:
Java 10 hat eine Inferenz des lokalen Variablentyps erhalten, daher hat es jetzt eine, var
die der C # 1 ziemlich weit entspricht (soweit mir bekannt ist).
Es kann auch auf nicht denotierbare Typen schließen (Typen, die vom Programmierer an dieser Stelle nicht benannt werden konnten; wobei die nicht denotierbaren Typen unterschiedlich sind). Siehe z. B. Tricks mit var
und anonyme Klassen (die Sie niemals bei der Arbeit verwenden sollten) .
Der einzige Unterschied, den ich finden konnte, ist der in C #,
In Java 10 var
ist kein legaler Typname.
Ab Java 10, ist das Äquivalent ... var
.
Ich weiß, dass dies älter ist, aber warum nicht eine var-Klasse erstellen und Konstruktoren mit unterschiedlichen Typen erstellen. Je nachdem, welche Konstruktoren aufgerufen werden, erhalten Sie var mit unterschiedlichen Typen. Sie können sogar Methoden einbauen, um einen Typ in einen anderen zu konvertieren.
Lombok
unterstützt var, ist aber immer noch als experimentell klassifiziert:
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);
Hier ist eine Gefahr, die Sie vermeiden sollten, wenn Sie versuchen, sie zu verwenden IntelliJ IDEA
. Es scheint jedoch wie erwartet zu funktionieren, einschließlich der automatischen Vervollständigung und allem. Bis es eine "nicht hackige" Lösung gibt (z. B. aufgrund von JEP 286: Typinferenz lokaler Variablen ), ist dies möglicherweise die beste Wahl.
Beachten Sie, dass dies auch von val
unterstützt wird, Lombok
ohne ein zu ändern oder zu erstellen lombok.config
.
Sie können in Java 10, aber nur für Local Variablen, dh
Sie können,
var anum = 10; var aString = "Var";
Aber kann nicht,
var anull = null; // Since the type can't be inferred in this case
Weitere Informationen finden Sie in der Spezifikation .
var
kann für viele Formen von nicht denotierbaren Typen verwendet werden, einschließlich Erfassungstypen, Schnittpunkttypen und anonymen Klassentypen. Ab Java 11 kann es auch auf Lambda-Parameter angewendet werden.
Im Allgemeinen können Sie die Objektklasse für jeden Typ verwenden, aber Sie müssen später Typumwandlung durchführen!
z.B:-
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
Wort, das jetzt offiziell in der Sprache ist, bezieht sich Ihre Antwort auch auf den jetzt altmodischen Weg.
Diese Funktion ist jetzt in Java SE 10 verfügbar. Die statische, typsichere Variable hat es endlich in die Java-Welt geschafft :)
Quelle: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
val
(odervar
) wenn Sie eine bestimmte "Java-Ersatz" -Sprache verwenden ;-)