2016-02-10 5 views
8

Vor einigen Tagen sprach ich mit meinen Kollegen über diesen Code in Java:Syntax mit verpassten Ausdruck für die Grund for-Schleife

for(; ;) { } 

Nichts Besonderes hier, nur eine Endlosschleife.

Aber wir fragen, warum diese syntaktisch korrekt ist. Wenn Sie einen Blick auf JLS §14.14.1 nehmen werden Sie sehen:

for ([ForInit] ; [Expression] ; [ForUpdate]) Statement 

Ich verstehe, dass ForInit und ForUpdate verzichtet werden kann. Aber zumindest würde ich erwarten, dass Expression zwingend vorgeschrieben ist, wie in while-Schleife:

while() {} // compile error, Expression is missed 

Warum kann Expression auf einer for-Schleife verzichtet werden? Und selbst einer denkt mehr - warum ist der verpasste Ausdruck in true aufgelöst? Meine Erwartung wäre, dass der leere Ausdruck in false aufgelöst wird.

das gleiche denken ist für andere Sprachen gültig (Ich versuche, habe es mit C und JavaScript, aber ich glaube, jeder Sprache mit for-Schleifen auf diese Weise verhält).

Warum ist ein Ausdruck Klausel nicht zwingend in for-Schleife (aber in while-Schleife)? Warum leerer Ausdruck zu true lösen und nicht false?

+6

Sie haben zu viel Zeit auf Ihre Hände, wenn Sie sich darüber sorgen :) – tokamak

+1

Interstingly, beide 'for (;;)' und 'while (true)' ae ersetzt mit nur einer 'goto 0' Anweisung: P – TheLostMind

+0

@tokamak machte meinen Tag: D – osanger

Antwort

3

Die Logik beginnt in JLS 14.14.1.1 und setzt sich in 14.14.1.2, Hervorhebung von mir.

Wenn der ForInit Teil nicht vorhanden ist, wird keine Aktion durchgeführt.

Wenn die Expressionnicht vorhanden, oder es vorhanden ist, und der Wert aus seiner Bewertung resultierenden (einschließlich etwaigen unboxing) wahr ist, dann ist die enthaltene Statement ausgeführt ...

Die JLS ermöglicht die leeren ForInit, Expression und ForUpdate Aussagen und hat Bedingungen mit ihrer Abwesenheit zu behandeln, so dass sie das Weglassen ist akzeptabel.

Es ist nicht zulässig so mit while Schleifen zu tun, per JLS 14.12.

Der Expression muss Typ boolean oder Boolean haben oder einen Fehler bei der Kompilierung auftritt.

Daraus die Spezifikation nicht einen leeren Ausdruck ermöglicht durchlaufen werden, da diese je zuvor in einem Fehler bei der Kompilierung führen würden.


Wenn Sie nach einem etwas mehr historischen Grund suchen, die C specification mandates this as well.

enter image description here

Da Java schwere Inspiration von C hat (und ist vor allem darin implementiert), macht es durchaus Sinn für Schleifen Java ähnlich der Schleifen zu C verhalten, und das ist, wie sie sich verhalten: Ausdrücke sind optional in C's for Erklärung, und verpflichtend in seiner while Aussage.

+1

Ja ... Ich habe JLS schon auch gesehen. Aber meine Frage war "warum" ist es so? –

+1

"Weil Oracle so sagte" ist das Beste, was Sie von hier aus tun können. Es ist auch konsistent mit C, auf dem Java hauptsächlich basiert. – Makoto

+2

Ich habe diese Frage geschrieben, weil ich hoffe, jemand hat eine bessere Antwort als "Weil Oracle so sagte". Sicher, ich glaube, dass Java es mit C. in Einklang bringt. Aber was ist der ursprüngliche Grund für diese Entscheidung? Vielleicht gibt es historische Gründe wie "es war einfacher Compiler auf diese Weise zu implementieren" oder "nur Fehler - aber aus Kompatibilitätsgründen wurde es danach nicht geändert". Vielleicht gibt es andere Gründe ... Meine Frage zielt darauf ab, dies herauszufinden. –

Verwandte Themen