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 varwurde 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 varSchlü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.
varist nicht dasselbe wie dynamic. variables sind immer noch zu 100% statisch typisiert. Dies wird nicht kompiliert:
var myString = "foo";
myString = 3;varist 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, currentUsereine Useroder eine abgeleitete Klasse enthalten ist. Wenn Ihre Implementierung von User.GetCurrentreturn 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 varohne 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 vardem statischen Typ psteht immer Xim ersten Beispiel oben, aber immer SuperXim zweiten Beispiel. Ein subtiler, aber wichtiger Unterschied, den man beachten muss. Aber deine Antwort ist sehr richtig :-)
varmacht 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();)? varlä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, varist unklar, ist es nur, weil es nicht daran gewöhnt ist.
varkann 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 radioButtonim 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.
varwie 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.
varselbst 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 .
finalsind 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 varin 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 varreservierten 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 varreservierte Typname in Java ist nahezu identisch mit dem varSchlüsselwort in C #, da beide eine implizite Typisierung ermöglichen (wichtige Unterschiede siehe unten). varin 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 varin 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 vares 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 varin 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.
varin Java & C.Dies ist ein bemerkenswerter Unterschied zwischen varC # und Java: varKann 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
varim Gültigkeitsbereich befindet, wird dasvarSchlüsselwort in diesen Typnamen aufgelöst und nicht als Teil einer implizit typisierten lokalen Variablendeklaration behandelt.
Die Möglichkeit, varin C # als Typname zu verwenden, führt zu einer gewissen Komplexität und führt einige komplizierte Auflösungsregeln ein, die varin Java vermieden werden, indem sie varals Klassen- oder Schnittstellenname nicht zugelassen werden. Informationen zur Komplexität von varTypnamen 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 .
varfür Felder oder Rückgabetypen verwenden können? Warum ist es wichtig zu beachten?
varin Java kann nicht für Felder oder Rückgabetypen verwendet werden. Dies ist wichtig, da diese Einschränkung varkontextsensitiv 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 varin Java.
vareinen 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.
varin 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 varJava und die Unterschiede zu varC # 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:
varist 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 varBeispiel listist 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, vardie 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 varund anonyme Klassen (die Sie niemals bei der Arbeit verwenden sollten) .
Der einzige Unterschied, den ich finden konnte, ist der in C #,
In Java 10 varist 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.
Lombokunterstü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 valunterstützt wird, Lombokohne 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 .
varkann 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);
varWort, 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 ;-)