Java geht

Es gibt einen alten Programmiererwitz, der ungefähr so ​​aussieht: Ein verärgerter Programmierer sagt zu dem zweiten Programmierer: "Fahr zur Hölle!" Der zweite Programmierer antwortet mit offensichtlicher Abstoßung: "Ugh, du hast goto benutzt!" Der Sinn dieses nerdigen Humors ist, dass die Verwendung von "goto" für viele Programmierer fast das schlimmste Vergehen ist, das man begehen kann.

Es gibt mehrere Gründe, warum das goto bei Softwareentwicklern so wenig geschätzt wird. Edsger W. Dijkstras Artikel A Case Against the GO TO Statement ist eine relativ frühe Abhandlung über die Übel des GOTO-Missbrauchs. In diesem Artikel stellt Dijkstra fest: "[Ich wurde] davon überzeugt, dass die Go-to-Anweisung von allen 'höheren' Programmiersprachen abgeschafft werden sollte." Dijkstras Go To Statement als schädlich eingestuft hat nicht nur die goto-Aussage verfälscht, sondern auch einen populären Informatik-Trend ausgelöst, den Ausdruck "als schädlich" zu verwenden (obwohl diese beiden Wörter zuvor offenbar außerhalb der Programmierung verwendet wurden).

Viele Programmierer seit Dijkstra wurden von einigen Wartbarkeitsproblemen gebissen, die mit der Verwendung von goto-Anweisungen in bestimmten Sprachen verbunden sind. Andere Programmierer haben diese Geschichten gehört oder haben das "Du sollst kein Goto verwenden" so sehr in sie hineingestoßen, dass sie ihre Nachteile nicht aus erster Hand erfahren müssen, um zu glauben, dass sie GOTO nicht verwenden sollten.

Obwohl die goto-Erklärung einen allgemein schlechten Ruf zu haben scheint, ist sie nicht ohne ihre Anhänger. Frank Rubin schrieb eine Antwort auf Dijkstras Go To Statement als schädlich(März 1968) genannt GOTO als schädlich angesehen 'als schädlich angesehen (März 1987). In diesem Brief schrieb Rubin über Dijkstras Brief, der sich so dramatisch auf Programmierer auswirkt, dass "die Vorstellung, dass GOT0 schädlich ist, fast allgemein akzeptiert wird, ohne Frage oder Zweifel." Über diese Beobachtung schrieb Rubin: "Dies hat dem Programmierbereich, der ein wirksames Werkzeug verloren hat, unkalkulierbaren Schaden zugefügt. Es ist wie bei Metzgern, die Messer verbieten, weil sich Arbeiter manchmal selbst schneiden." Beachten Sie, dass Dijkstra auf Rubins Brief mit einer etwas enttäuschenden Korrespondenz antwortete. Die Cunningham & Cunningham Wiki-Seite Go To sagt dies über die goto-Aussage: "Der Lehrling benutzt es ohne nachzudenken. Der Geselle vermeidet es ohne nachzudenken. Der Meister benutzt es nachdenklich."

Es gibt zahlreiche andere Ressourcen, die die Vor- und Nachteile der Verwendung der goto-Anweisung abdecken. Ich beabsichtige nicht, diese Debatte hier zu wiederholen, außer der kurzen Darstellung der frühen Geschichte der bereits behandelten Kontroverse. Ich habe einige Java-Entwickler gehört, die sagten, dass Java keine goto-Anweisung hat, und das möchte ich im Rest dieses Blog-Beitrags diskutieren.

Java reserviert "goto" als reserviertes Schlüsselwort. Es ist jedoch ein nicht verwendetes Schlüsselwort. Dies bedeutet, dass das Schlüsselwort zwar eigentlich nichts Produktives bewirkt, aber auch ein Wort ist, das im Code nicht für Namen von Variablen oder anderen Konstrukten verwendet werden kann. Der folgende Code wird beispielsweise nicht kompiliert:

package dustin.examples; /** * Class demonstrating Java's goto-like functionality. */ public class JavaGotoFunctionality { /** * Main executable function. * * @param arguments Command-line arguments: none expected. */ public static void main(final String[] arguments) { final String goto = "Go to bed!"; } } 

Wenn ich versuche, diesen Code zu kompilieren, wird ein Fehler wie im nächsten Screenshot angezeigt.

Die Fehlermeldung "erwartet" mit einem Zeiger auf das Leerzeichen vor "goto" gibt einem erfahrenen Java-Entwickler genügend Hinweise, um schnell zu erkennen, dass bei der Verwendung von "goto" etwas nicht stimmt. Für jemanden, der neu in Java ist, ist dies jedoch möglicherweise nicht so offensichtlich.

Ich verwende das goto-Konstrukt im Allgemeinen nicht, aber ich erkenne auch, dass es Situationen gibt, in denen seine Verwendung zu besser lesbarem Code führt und weniger verrückte Workarounds verwendet, als wenn er nicht verwendet wird. In Java wurde dies ebenfalls erkannt und es werden einige der häufigsten Situationen unterstützt, in denen eine goto-Anweisung am nützlichsten und wahrscheinlich Alternativen vorzuziehen wäre. Die offensichtlichsten Beispiele hierfür sind die beschrifteten breakund beschrifteten continueAussagen. Diese werden im Abschnitt Verzweigungsanweisungen für Java-Tutorials erläutert und demonstriert.

Die Möglichkeit, eine bestimmte Anweisung zu kennzeichnen und dann die Anweisung zu verwenden breakoder continueauf diese Anweisung anzuwenden, anstatt ihre unmittelbarste Anweisung (als unbeschriftet breakoder continuenicht), ist besonders nützlich in Fällen, in denen verschachtelte Schleifen ansonsten mehr Code und komplexeren Code erfordern würden, um dies zu erreichen Sache. Ich habe festgestellt, dass ich meine Datenstrukturen und meinen Code häufig neu gestalten kann, um solche Situationen zu vermeiden, aber dies ist nicht immer praktisch.

Eine weitere gute Ressource im Zusammenhang mit der Verwendung von goto-ähnlichen Funktionen in Java sind die JDC Tech Tip Goto-Anweisungen und die Java-Programmierung vom 13. Juni 2000. Wie dieser Tipp hervorhebt, können die Beschriftungen tatsächlich für jeden Block verwendet werden und sind nicht auf breakund beschränkt continue. Ich habe jedoch die Erfahrung gemacht, dass die Notwendigkeit dieses Ansatzes außerhalb breakund continueweit weniger verbreitet ist.

Eine wichtige Beobachtung zu Labels ist, dass die Codeausführung nicht buchstäblich zu diesem Label zurückkehrt, wenn das break somelabelausgeführt wird. Stattdessen geht der Ausführungsfluss zu der Anweisung, die unmittelbar auf die gekennzeichnete Anweisung folgt. Wenn ich zum Beispiel eine äußere forSchleife mit dem Namen "Dustin:" hätte, würde eine Unterbrechung dieser Schleife tatsächlich zur ersten ausführbaren Anweisung nach dem Ende dieser beschrifteten forSchleife führen. Mit anderen Worten, es verhält sich eher wie ein Befehl "gehe zu der Anweisung, die der beschrifteten Anweisung folgt".

Ich gebe hier keine Beispiele für die Verwendung dieser gekennzeichneten breakoder gekennzeichneten continueAussagen an, da es viele gute Beispiele gibt, die leicht online zu finden sind. Insbesondere enthalten die beiden Ressourcen, die ich bereits erwähnt habe (Java Tutorials Branching Statements und Goto Statements sowie Tech-Tipp zur Java-Programmierung), einfache veranschaulichende Beispiele.

Je mehr ich in der Softwareentwicklungsbranche arbeite, desto mehr bin ich davon überzeugt, dass es in der Softwareentwicklung nur wenige Absolute gibt und dass extremistische Positionen an der einen oder anderen Stelle fast immer falsch sein werden. Ich scheue mich im Allgemeinen davor, goto oder goto-ähnlichen Code zu verwenden, aber es gibt Zeiten, in denen dies der beste Code für den Job ist. Obwohl Java keine direkte goto-Unterstützung bietet, bietet es goto-ähnliche Unterstützung, die die meisten meiner relativ seltenen Anforderungen an eine solche Unterstützung erfüllt.

Diese Geschichte "Java's goto" wurde ursprünglich von JavaWorld veröffentlicht.