Verlassen Sie sich auf die Standardfeldinitialisierung - ist der Programmierstil schlecht? [geschlossen]

20

Ich erhielt einen Link zur offiziellen Oracle-Dokumentation: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

wo es heißt:

Standardwerte

Es ist nicht immer erforderlich, einen Wert zuzuweisen, wenn ein Feld deklariert wird. Felder, die deklariert, aber nicht initialisiert sind, werden vom Compiler auf einen angemessenen Standardwert gesetzt. Im Allgemeinen ist dieser Standardwert je nach Datentyp Null oder Null. Das Verlassen auf solche Standardwerte wird jedoch allgemein als schlechter Programmierstil angesehen.

Ich möchte diesen Teil hervorheben:

Das Verlassen auf solche Standardwerte wird jedoch allgemein als schlechter Programmierstil angesehen.

Aber, oh Mann, das ist, würde ich sagen, ein grundlegender Teil der Sprachspezifikation, wenn man weiß, dass Instanzvariablen Standardwerte haben. Warum um alles in der Welt ist dies eine schlechte Programmierpraxis, wenn sie selbst im Quellcode von Java SE-Bibliotheken weit verbreitet ist?

Andremoniy
quelle
5
Huh. Ich wusste nie, dass diese Aussage da drin war. Ich halte es eigentlich für eine gute Praxis, sich auf sie zu verlassen. private int count = 0;ist Code, der nichts tut, und Code, der nichts tut, ist Unordnung. Es ist wie das Importieren von Klassen aus java.lang oder das Deklarieren einer Klasse mit extends Object.
VGR
2
... oder eine public abstractMethode in einer Schnittstelle haben.
Mumpitz
1
Was ist los mit öffentlichen Abstracts?
John Keates
1
Ein Teil des Puzzles kann aus C ++ stammen. Es ist eine beliebte Sprache, und die Behandlung der Standardinitialisierung im Vergleich zur Nullinitialisierung ist eine kontinuierliche Fehlerquelle. In C ++ ist es eine schlechte Idee, sich in allen außer den Ausnahmefällen auf die Standardeinstellungen zu verlassen. Das könnte kulturell in Java durchgesickert sein.
Cort Ammon
@JohnKeates - Mein Java ist etwas verrostet, aber privateMethoden in einer Schnittstelle machen keinen Sinn und abstractsind impliziert.
Scott Smith

Antworten:

6

Der zitierte Text lautet:

"Das Verlassen auf solche Standardwerte wird jedoch allgemein als schlechter Programmierstil angesehen."

Zynisch: "Es wird allgemein angenommen, dass" ist oft eine Art zu sagen, dass der Autor nicht versucht hat, eine maßgebliche Quelle für die präsentierte Aussage zu finden.

In diesem Fall ist die Behauptung eindeutig fraglich. Beweis: 5 von 5 Java Style Guides in der Stichprobe sagen nichts darüber aus, ob Sie sich auf Standardwerte verlassen sollten oder sollten:

(Beachten Sie, dass meine Methode für die Stichprobe darin bestand, die ersten 5 verschiedenen Google-Suchtreffer nach "Java Style Guide" zu untersuchen. Dann habe ich jedes Dokument nach "Standard" durchsucht. Dies ist keine gründliche Analyse, aber es dient dazu, meinen Standpunkt zu verdeutlichen. )


OK. Hilft es also wirklich bei der Lesbarkeit von Java-Code?

Das ist umstritten.

Einerseits kann ein unerfahrener Java-Programmierer, der nichts über die Standardinitialisierung gelernt hat, verwirrt darüber sein, woher die Nullen oder Nullen kommen. Wenn sie sich jedoch die Mühe machen, nach einer expliziten Initialisierung zu suchen und feststellen, dass es keine gibt, sollte dies ausreichen, um sie zu veranlassen, ein Lernprogramm oder ein Buch zu lesen, um Informationen zur Standardinitialisierung zu erhalten. (Sie würden hoffen!)

Andererseits erwarten wir normalerweise nicht, dass unerfahrene Java-Programmierer Produktionscode-Basen beibehalten. Für einen erfahrenen Java-Programmierer verbessert eine redundante Initialisierung die Lesbarkeit nicht. Es ist (bestenfalls) Lärm.

Meiner Meinung nach ist das einzige, was durch eine redundante Initialisierung eines Feldes erreicht wird, einem zukünftigen Leser Ihres Codes zu signalisieren, dass Sie über den Anfangswert nachgedacht haben. (Wie @GhostCat es ausdrückte, kommuniziert die Standardinitialisierung keine Absicht.)

Aber umgekehrt, wenn ich dieser Leser wäre, würde ich dem Denken des Code-Autors nicht unbedingt vertrauen. Der Wert dieses "Signals" ist also ebenfalls fraglich.


Was ist mit Zuverlässigkeit?

In Java macht es keinen Unterschied. Die JLS gibt an, dass Standardinitialisierung nicht für Felder auftreten. Umgekehrt ist es für lokale Variablen ein Kompilierungsfehler, zu versuchen, eine Variable zu verwenden, die nicht definitiv initialisiert wurde.

Kurz gesagt, das Laufzeitverhalten einer nicht explizit initialisierten Variablen ist vollständig vorhersehbar.

Im Gegensatz dazu ist das Verhalten in Sprachen wie C oder C ++, in denen Variablen möglicherweise nicht initialisiert werden, nicht angegeben und kann zu Abstürzen und Verhaltensunterschieden auf verschiedenen Plattformen führen. Die Argumentation, Variablen immer explizit zu initialisieren, ist hier viel stärker.


Was ist mit Leistung?

Es sollte keinen Unterschied machen. Der JIT-Compiler sollte in der Lage sein, eine redundante Initialisierung und eine Standardinitialisierung als gleich zu behandeln.

Stephen C.
quelle
19

Einfach: Wenn Sie sich auf Standardwerte verlassen, wird keine Absicht kommuniziert.

Wollten Sie wirklich, dass dieses Feld mit 0 beginnt, oder haben Sie vergessen , einen Wert zuzuweisen?!

Und natürlich ist eine Nullreferenz die Hälfte der beiden Dinge, die Sie benötigen, um auf eine Nullzeigerausnahme zu stoßen.

Schließlich bedeutet die Verwendung von Standardeinstellungen, dass Sie nicht endgültige Felder haben. Was Sie nach Möglichkeit vermeiden.

Das einzige Gegenargument ist: Warum Dinge aufschreiben, die Sie nicht müssen? Aber ich denke, die aufgeführten Nachteile trompeten, dass es besser ist, einem Feld explizit 0 zuzuweisen, als es dem Compiler zu überlassen.

GhostCat begrüßt Monica C.
quelle
3
dh bezüglich: keine Absicht kommunizieren - Was ist, wenn "Manny der Betreuer" Ihren Code betrachtet und nicht weiß, was die Standardeinstellung für einen bestimmten Datentyp ist. Er geht davon aus, dass es 0 ist, wenn es wirklich NULL ist, und das ist der gesamte Fehler bei einer ===-Prüfung (oder was auch immer die äquivalente Gleichheitsprüfung für Wert und Typ in Java ist, equals ()?). Stundenlanges Suchen (nach einem unerfahrenen Programmierer) könnte das Ergebnis von etwas so Einfachem sein. PS versucht, den Anwalt des Teufels zu spielen. Ich sage, benutze die Standardeinstellungen den ganzen Tag (obwohl ich das nie tue) und bringe klügere Leute (oder zumindest mehr Liebe zum Detail) dazu, deinen Code zu pflegen.
TCooper
@TCooper Wenn Mannie, der Betreuer, so wenig über Java weiß, hat er nichts damit zu tun, Java-Code aus der realen Welt zu berühren. Aber ich stimme dem zugrunde liegenden Begriff zu. Es macht die Dinge für Neulinge schwieriger.
GhostCat begrüßt Monica C.
12

Warum um alles in der Welt ist das eine schlechte Programmierpraxis?

Die Idee ist, wenn Sie sich auf einen Standardwert verlassen, ist es für niemanden, der den Code liest, sofort klar, wenn Sie ihn absichtlich als Standardwert belassen oder einfach vergessen haben, ihn zuzuweisen.

... wenn es auch im Quellcode von Java SE-Bibliotheken weit verbreitet ist?

Der Java-Quellcode ist nicht wirklich etwas, auf das Sie sich als Beispiel für eine beispielhafte Codierungspraxis verlassen sollten. Es gibt viele Fälle, in denen solche Regeln verletzt werden (manchmal absichtlich für geringfügige Leistungsverbesserungen und manchmal versehentlich oder weil sich der akzeptierte Stil im Laufe der Jahre geändert hat).

Michael Berry
quelle
2
Dies ist wahrscheinlich richtig, obwohl ich damit nicht einverstanden bin.
VGR
3
@VGR So sehr ich der Behauptung zustimme, dass das Verlassen auf Standardwerte nicht optimal ist, habe ich es aus diesem Grund sorgfältig neutral formuliert. Die Codequalität ist subjektiv, und mir ist klar, dass dies keineswegs eine universelle Ansicht ist.
Michael Berry