Gibt es in Java automatische Typableitungen?

113

Gibt es autoin Java einen Variablentyp wie in C ++?

Ein Beispiel:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

Ich weiß, dass es in Java eine erweiterte for-Schleife gibt, aber gibt es eine automatische? Wenn nicht, gibt es einen Hack dazu? Ich beziehe mich auf die neue Funktion in C ++ 11

Spiele Brainiac
quelle
1
Alles außer grundlegenden Typen kann einer Variablen vom Typ zugewiesen werden Object, sodass Sie für einige Operationen verwenden können, Objectwo Sie möchten auto.
Zyx 2000
1
Kein Java hat keine solche Variable
Aleksei Bulgak
@ Zyx2000: Dann wird die Objektfunktion verwendet to_stringund nicht das betreffende Objekt , nicht wahr ?
Spiele Brainiac
2
@GamesBrainiac: Nein, es wird die überschriebene Version verwendet, falls vorhanden.
Keppil
2
Der Begriff, den Sie suchen, ist nicht "auto", sondern "Typinferenz". Es gibt einige Fragen zur Typinferenz in Java, obwohl sie sich hauptsächlich auf Generika beziehen, daher bin ich mir nicht sicher, wie ich ein Duplikat finden soll ...

Antworten:

49

Beantwortet, bevor die Frage bearbeitet wurde :

Nein, autoin Java gibt es keinen Variablentyp. Die gleiche Schleife kann erreicht werden als:

for ( Object var : object_array)
  System.out.println(var);

Java verfügt über lokale Variablen, deren Gültigkeitsbereich innerhalb des Blocks liegt, in dem sie definiert wurden. Ähnlich wie C und C ++, aber es gibt kein Auto- oder Register-Schlüsselwort. Der Java-Compiler erlaubt jedoch nicht die Verwendung einer nicht explizit initialisierten lokalen Variablen und gibt einen Kompilierungsfehler aus (im Gegensatz zu C und C ++, wo der Compiler normalerweise nur eine Warnung ausgibt). Mit freundlicher Genehmigung von Wikipedia .

Nein, in Java gibt es keine gängigen Typinferenzen wie in C ++. Es gab eine RFE , diese wurde jedoch als "Wird nicht behoben" geschlossen. Der angegebene Grund war:

Menschen profitieren auf zwei Arten von der Redundanz der Typdeklaration. Erstens dient der redundante Typ als wertvolle Dokumentation - Leser müssen nicht nach der Deklaration von getMap () suchen, um herauszufinden, welchen Typ er zurückgibt. Zweitens ermöglicht die Redundanz dem Programmierer, den beabsichtigten Typ zu deklarieren und dadurch von einer vom Compiler durchgeführten Gegenprüfung zu profitieren.

NINCOMPOOP
quelle
10
@GamesBrainiac Nein, Methodenaufrufe sind in Java immer polymorph. Viele andere Dinge (z. B. Überlastungsauflösung oder nicht definierte Vorgänge Object) können jedoch nicht so ausgeführt werden. Dies ist keine wirklich gute Antwort, es funktioniert nur, weil das Beispiel in der Frage schwach ist.
10
Diese Frage bezieht sich auf die Typinferenz in C ++ 11, nicht auf die alte Verwendung autoin C und vor C ++ 11. Ihre Bearbeitung ist nicht zum Thema.
4
"Das ist nicht das, was ich gemeint habe. Wenn Sie es in ein Objekt umwandeln, erhalten Sie die to_string des Objekts." False. Absolut 100% falsch.
Louis Wasserman
140
"Der Mensch profitiert von der Redundanz." Es ist wahr. Jeden Morgen wache ich auf und denke: "Wie kann ich meinen Code redundanter machen?". Wegen der Vorteile.
Hofhoffer
2
Darüber hinaus ist diese Antwort veraltet, da sie varseit Java 9 reserviert ist.
6infinity8
69

Könnte sein, dass Java 10 über das varSchlüsselwort das hat, was Sie (und ich) wollen .

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

Aus JDK-Verbesserungsvorschlägen 286


Update: Ja, diese Funktion hat es in die Java 10-Version geschafft!

sorrymissjackson
quelle
6
Ja, es ist eine Verbesserung, aber dieses Schlüsselwort kann nur mit lokalen Variablen funktionieren. Nicht so leistungsfähig wie C ++ Auto Type
Inference
7
Minor nit-pick: varist kein Schlüsselwort! Aus dem JLS : "var ist kein Schlüsselwort, sondern ein Bezeichner mit besonderer Bedeutung als Typ einer lokalen Variablendeklaration". Im Gegensatz zu Schlüsselwörtern hindert Sie nichts daran, eine Variable oder eine Methode "var" aufzurufen.
Klitos Kyriacou
2
Guter Punkt @KlitosKyriacou. Wenn ich mir jedoch vorstelle, 'Schlüsselwort' durch 'Bezeichner' oder sogar 'Bezeichner mit besonderer Bedeutung als Typ einer lokalen Variablendeklaration' zu ersetzen, wäre die Antwort meiner Meinung nach weniger klar. Aber ja, varist in der Tat nicht in der Liste der Schlüsselwörter.
Sorrymissjackson
Es ist kein Schlüsselwort, nur um die Abwärtskompatibilität zu gewährleisten. Neben der Tatsache, dass Sie einen Bezeichner mit diesem Namen haben können, spielt var die Rolle eines Schlüsselworts.
Facetus
25

Java 7 führt die Diamantsyntax ein

Box<Integer> integerBox = new Box<>(); // Java 7

Im Vergleich zu altem Java

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

Der kritische Leser wird feststellen, dass diese neue Syntax beim Schreiben der for-Schleifen in der ursprünglichen Frage nicht hilfreich ist. Das ist richtig und völlig beabsichtigt, wie es scheint. Siehe die andere Antwort, in der die Fehlerdatenbank von Oracle zitiert wird.

Tarrasch
quelle
4
Stimmt, aber was er (und ich) suchen, ist ungefähr so: auto integerBox = new Box<Integer>();Dies wird normalerweise verwendet, um einen Rückgabewert von Funktionen zu erhalten, die manchmal komplexiert werden können wieHashMap<String, LinkedList<Operation, Set<Integer>>>
Roee Gavirel
1
Dieses Problem habe ich genau nach den Codebeispielen angesprochen. Die Schlussfolgerung war, dass Java das nicht tut, und das ist absichtlich so.
Tarrasch
18

In Java 8 können Sie die Lambda-Typinferenz verwenden, um zu vermeiden, dass der Typ deklariert wird. Das Analogon zu den Beispielen des Fragestellers wäre:

object_array.forEach(var -> System.out.println(var)); 
object_array.forEach(var -> var.do_something_that_only_this_particular_obj_can_do());

Beide können auch mithilfe von Methodenreferenzen vereinfacht werden:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);
Ajit George
quelle
8

Kurz gesagt, nein, es gibt keinen automatischen Typ. Wenn Sie jedoch nur den Wert drucken, können Sie den Wert einfach als bezeichnen Object.

SimonC
quelle
oder hashCodes berechnen oder Klassennamen sammeln oder ... Sie haben die Idee;) Die Liste ist jedoch kurz. Siehe Objektklasse 'Dokumente (Kommentar für Anfänger gedacht, ich bin sicher, Sie wussten es SimonC)
Alexander Malakhov
4

Es ist keine reine Java-Lösung. Wenn Sie jedoch eine Bibliothek namens lombok hinzufügen, kann die folgende Magie das autoSchlüsselwort in C ++ kompilieren und sehr ähnlich funktionieren

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
samvel1024
quelle