Google-Handbuch zum Formatieren von Java-Code

Bild

1. Einleitung



Dieses Dokument beschreibt die Standards für die Codierung in der Programmiersprache Java bei Google. Java-Quellcode entspricht diesen Standards nur dann, wenn er alle in diesem Dokument beschriebenen Regeln erfüllt.



In diesem Tutorial behandelte Themen befassen sich nicht nur mit der ästhetischen Seite der Code-Formatierung, sondern auch mit anderen Arten von Codierungskonventionen oder -standards. Dieses Dokument konzentriert sich jedoch in erster Linie auf die Definition der strengen Regeln, die wir überall befolgen, und enthält keine Empfehlungen, die falsch implementiert werden können (sowohl von Menschen als auch von Werkzeugmaschinen).



1.1 Terminologie



In diesem Handbuch werden die folgenden Begriffe definiert:



  1. Der Begriff Klasse wird verwendet, um eine "reguläre" Klasse, Aufzählung, Schnittstelle oder einen Annotationstyp (@interface) zu bezeichnen.
  2. Der Begriff Klassenmitglied wird verwendet, um sich auf eine verschachtelte Klasse, ein verschachteltes Feld, eine verschachtelte Methode oder einen verschachtelten Konstruktor zu beziehen, dh für alle übergeordneten Klassenmitglieder mit Ausnahme von Initialisierungsblöcken und Kommentaren.
  3. Der Begriff Kommentar bezieht sich immer auf Implementierungskommentare. Wir verwenden nicht den Ausdruck "Dokumentationskommentare", sondern den Begriff "Javadoc".


Der Rest der Terminologie wird nach Bedarf in diesem Handbuch bereitgestellt.



1.2 Manueller Hinweis



Die Codebeispiele in diesem Dokument zeigen nicht den einzig richtigen stilistischen Ansatz für die Formatierung, obwohl sie in unserem Lernprogramm verwendet werden.



2. Quelldatei. Die Grundlagen



2.1 Dateiname



Ein Quelldateiname besteht aus dem Namen einer bestimmten Klasse der obersten Ebene, die sich darin befindet. Der Name unterscheidet zwischen Groß- und Kleinschreibung und endet mit der Erweiterung .java



2.2 Dateicodierung: UTF-8



Dateien mit Code werden in UTF-8 codiert.



2.3 Sonderzeichen



2.3.1 Leerzeichen



Abgesehen von der Zeilenendezeichenfolge ist das horizontale ASCII-Leerzeichen (0x20) das einzige Trennzeichen in der Quelldatei. Es bedeutet, dass:



  1. Alle anderen Leerzeichen in Zeichen- und Zeichenfolgenliteralen werden maskiert
  2. Tabulatorzeichen werden nicht zum Einrücken verwendet


2.3.2 Spezielle Escape-Sequenzen



Für jedes Zeichen, für das es eine spezielle Escape-Sequenz gibt (\ b, \ t, \ n, \ f, \ r, \ ", \ 'und \\), ist es vorzuziehen, es anstelle seines entsprechenden Oktalwerts (z. B. \ 012) zu verwenden ) oder Unicode-Code (z. B. \ u000a).



2.3.3 Nicht-ASCII-Zeichen



Verwenden Sie für Nicht-ASCII-Zeichen das Unicode-Zeichen (z. B. ∞) oder eine äquivalente Escape-Sequenz (z. B. \ u221e). Die Wahl wird zugunsten der Symbole getroffen, die den Code verständlicher und lesbarer machen.



Bei Verwendung von Unicode-Escape-Zeichen und in Fällen, in denen gültige Unicode-Zeichen verwendet werden, wird dringend empfohlen, diesen Code mit erläuternden Kommentaren zu versehen.


Beispiel Hinweis
String unitAbbrev = "μs" Hervorragend: auch ohne Kommentar perfekt wahrgenommen
String unitAbbrev = "\ u03bcs" // "μs" Erlaubt, aber kein Grund dazu
String unitAbbrev = "\ u03bcs" // Griechischer Buchstabe mu, "s" Erlaubt aber umständlich und kann zu Fehlern führen
String unitAbbrev = "\ u03bcs" Schlecht: Der Leser hat keine Ahnung, was es ist
return '\ ufeff' + content // byte order sign Gut: Verwenden Sie Escape für nicht druckbare Zeichen und kommentieren Sie sie nach Bedarf


Machen Sie Ihren Code niemals weniger lesbar, nur aus Angst, dass einige Programme Nicht-ASCII-Zeichen nicht korrekt verarbeiten können. In diesem Fall funktionieren solche Programme nicht richtig und müssen repariert werden.


3. Struktur der Quelldatei



Die Quelldatei besteht aus den folgenden Elementen (in der angegebenen Reihenfolge):



  1. Gegebenenfalls Lizenz- oder Copyright-Informationen
  2. Paketdeklaration
  3. Importe deklarieren
  4. Klassenerklärung


Genau eine Leerzeile trennt jeden vorhandenen Abschnitt.



3.1 Lizenz- oder Copyright-Informationen, falls vorhanden



Lizenz- oder Copyright-Informationen müssen in der Datei enthalten sein, auf die sie sich beziehen.



3.2 Paketdeklaration



Das Paket wird ohne Zeilenumbruch deklariert. Die Zeilenbreitenbeschränkung (Abschnitt 4.4) gilt nicht für eine Paketdeklaration.



3.3 Einfuhranmeldungen



3.3.1 Platzhalter in Einfuhranmeldungen



Das Zeichen * (Platzhalter) wird nicht verwendet, wenn Importe statisch oder nicht deklariert werden.



3.3.2 Zeilenumbruch



Importe werden ohne Zeilenumbrüche deklariert. Sie unterliegen nicht der Linienbreitenbeschränkung.



3.3.3 Reihenfolge und Abstand



Importe werden wie folgt bestellt:



  1. Alle statischen Importe werden in einem Block platziert und gruppiert
  2. Alle nicht statischen Importe werden in einem anderen Block abgelegt


Wenn sowohl statische als auch nicht statische Importe deklariert sind, müssen diese Blöcke durch eine leere Zeile getrennt werden. Zwischen ihnen sollten keine anderen Leerzeilen stehen.



Innerhalb jedes Blocks werden die importierten Klassen in der Sortierreihenfolge der ASCII-Zeichen aufgelistet.



3.3.4 Statischer Import verschachtelter Klassen



Statische Importe werden nicht für statisch verschachtelte Klassen verwendet. Solche Klassen werden mit einer regulären Importdeklaration importiert.



3.4 Klassenerklärung



3.4.1 Es wird genau eine Klasse der obersten Ebene deklariert



Jede Klasse der obersten Ebene befindet sich in einer eigenen Quelldatei.



3.4.2 Inhalt einer Klasse bestellen



Die Reihenfolge, in der Sie die Mitglieder und Initialisierungsblöcke einer Klasse platzieren, kann einen großen Einfluss darauf haben, wie einfach Ihr Code zu verstehen ist. In beiden Fällen gibt es dafür kein einfaches und korrektes Rezept. Verschiedene Klassen können ihren Inhalt auf unterschiedliche Weise anordnen.



Wichtig ist, dass jede Klasse eine logische Reihenfolge der Inhalte hat, damit der Programmierer, der den Code liest, dies erklären kann.



3.4.2.1 Überladener Code sollte nicht aufgeteilt werden



Wenn eine Klasse mehrere Konstruktoren oder Methoden mit demselben Namen hat, müssen sie nacheinander platziert werden, ohne dass dazwischen anderer Code eingefügt wird.



4. Formatierung



Terminologie



Der Hauptteil einer Klasse, Methode oder eines Konstruktors ist eine Blockkonstruktion .



Beachten Sie, dass gemäß Abschnitt 4.8.3.1 jeder Array-Initialisierer auch als Blockkonstrukt betrachtet werden kann.



4.1 Geschweifte Klammern



4.1.1 Geschweifte Klammern werden überall dort verwendet, wo sie verwendet werden dürfen



Geschweifte Klammern werden in if, else, for, while und do-while verwendet, selbst wenn der Hauptteil des Ausdrucks leer ist oder nur eine Codezeile enthält.



4.1.2 Nicht leere Blöcke: K & R-Stil



Geschweifte Klammern werden nach dem Stil von Kernighan und Ritchie ("ägyptische Klammern") für nicht leere Blöcke und Blockstrukturen platziert (aus Gründen der Klarheit haben wir beschlossen, einen kleinen Code hinzuzufügen, der diese Regeln demonstriert - Anmerkung des Übersetzers):



  • Vor der öffnenden Klammer wird kein Zeilenumbruch durchgeführt:


// 
if (true) { 

// 
if (true)
{


  • Nach der öffnenden Klammer wird ein Zeilenumbruch ausgeführt:


// 
while (true) {
  // code

// 
while (true) { // code


  • Vor der schließenden Klammer wird ein Zeilenumbruch durchgeführt:


// 
for () {
  // code
}

// 
while (true) { /* code */ }

// 
if (true) {
  /* code */ }


  • Ein Zeilenumbruch tritt nach einer schließenden Klammer nur dann auf, wenn diese Klammer einen Ausdruck oder einen Textkörper einer Methode, eines Konstruktors oder einer nicht anonymen Klasse beendet. Zeilenumbrüche werden nach einer Klammer nicht ausgeführt, wenn ein else, ein catch oder ein Semikolon folgt


Beispiele für korrekt ausgeführte Regeln:



return () -> {
  while (condition()) {
    method();
  }
};

return new MyClass() {
  @Override public void method() {
    if (condition()) {
      try {
        something();
      } catch (ProblemException e) {
        recover();
      }
    } else if (otherCondition()) {
      somethingElse();
    } else {
      lastThing();
    }
  }
};


Einige Ausnahmen für Aufzählungen sind in Abschnitt 4.8.1 aufgeführt



4.1.3 Leere Blöcke können komprimiert werden



Ein leerer Block oder ein leeres Blockkonstrukt kann dem K & R-Stil folgen (wie in Abschnitt 4.1.2 beschrieben). Es ist auch möglich, dass ein solcher Block unmittelbar nach dem Öffnen geschlossen wird, ohne dass Zeichen oder Zeilenumbrüche in {} enthalten sind. Diese Regel gilt nicht, wenn der Block Teil eines Mehrblockausdrucks ist, der ein if-else oder try-catch-finally enthält.



Beispiele:



// 
void doNothing() {}

//  
void doNothingElse() {
}

// :       
try {
  doSomething();
} catch (Exception e) {}


4.2 Zwei Leerzeichen zum Einrücken



Jedes Mal, wenn ein neuer Block oder ein neues Blockkonstrukt geöffnet wird, wird der Versatz nach rechts um zwei Leerzeichen erhöht. Wenn ein Block endet, wird der Anfang der nächsten Codezeile auf die vorherige Versatzstufe verschoben. Die Versatzstufe gilt sowohl für den Block als auch für die Kommentare in diesem Block (siehe ein Beispiel in Abschnitt 4.1.2).



4.3 Ein Ausdruck pro Zeile



Jeder Ausdruck endet mit einem Zeilenumbruch.



4.4 Begrenzung der Zeilenbreite auf 100 Zeichen



Java-Code ist auf 100 Zeichen in der Zeilenbreite begrenzt. Ein "Zeichen" bezieht sich auf eines der Unicode-Elemente. Außer wie unten beschrieben, muss jede Linie, die die Breitengrenze überschreitet, wie in Abschnitt 4.5 erläutert umbrochen werden.



Ausnahmen:



  1. , (, URL Javadoc JSNI- )
  2. package import (. 3.2 3.3)
  3. ,


4.5





Wenn Code, der sich ansonsten möglicherweise in derselben Zeile befindet, auf mehrere Zeilen aufgeteilt wird, wird dieses Phänomen als Zeilenumbruch bezeichnet.



Es gibt keine allgemein akzeptierte eindeutige Formel, die genau bestimmt, wie Zeilenumbrüche in jeder Situation ausgeführt werden sollen. Sehr oft gibt es mehrere Möglichkeiten, eine Zeile mit demselben Code zu unterbrechen.



Normalerweise wird umbrochen, um einen Überlauf der Linienbreite zu vermeiden. Aber selbst wenn der Code innerhalb der zulässigen Breite bleiben würde, kann er nach Entscheidung des Autors in eine neue Zeile eingeschlossen werden.



Das Zuweisen einer Hilfsmethode oder einer lokalen Variablen kann das Problem des Zeilenbreitenüberlaufs lösen, ohne den Code zu umbrechen


4.5.1 Überweisungsort



Die erste Richtlinie für Zeilenumbrüche lautet: Es ist vorzuziehen, den Zeilenumbruch auf einer höheren syntaktischen Ebene durchzuführen. Außerdem:



1. Wenn eine Zeile in einer Nichtzuweisungsanweisung unterbrochen wird, erfolgt die Unterbrechung vor dem Zeichen.



Diese Regel gilt auch für die folgenden "Operator-ähnlichen" Zeichen:



  • Teilungspunkt "."
  • Doppelter Doppelpunkt der Referenzmethode "::"
  • kaufmännisches Und in Klammern generisch <T erweitert Foo & Bar>
  • Trennzeichen im catch-Block (FooException | BarException e)


2. Wenn eine Zeichenfolge in eine Zuweisungsanweisung eingeschlossen wird, erfolgt der Zeilenumbruch normalerweise nach dem Zeichen. Eine andere Lösung



ist jedoch akzeptabel. Dies gilt auch für den Doppelpunkt für jede Schleife.



3. Der Name der Methode oder des Konstruktors, wenn die Zeilenumbrüche angezeigt werden, bleibt an der öffnenden Klammer "("



4. Das Komma "," wenn die Zeilenumbrüche bei dem vorangegangenen Element verbleiben.



5. Die Zeile wird niemals direkt am Pfeil des Lambda-Ausdrucks umbrochen, außer wenn sein Körper besteht aus einem einzigen Ausdruck ohne geschweifte Klammern:



MyLambda<String, Long, Object> lambda =
    (String label, Long value, Object obj) -> {
        ...
    };

Predicate<String> predicate = str ->
    longExpressionInvolving(str);


Der Hauptzweck von Zeilenumbrüchen besteht darin, Klarheit im Code zu erreichen, jedoch nicht unbedingt die kleinste Anzahl von Zeilen


4.5.2 Versetzung der Linienfortsetzung um 4 oder mehr Leerzeichen



Wenn eine Zeile unterbrochen wird, wird jeder nachfolgende Teilstring (jede Zeilenfortsetzung) gegenüber dem vorherigen um mindestens 4 Leerzeichen verschoben.



Bei mehreren Zeilenfortsetzungen kann der Versatz auf Wunsch des Autors innerhalb von 4 Leerzeichen variieren. In der Regel können zwei Zeilenerweiterungen genau dann den gleichen Versatz haben, wenn sie mit syntaktisch parallelen Elementen beginnen.



Abschnitt 4.6.3 enthält Anleitungen zur Verwendung unterschiedlicher Leerzeichen, um Codepunkte relativ zu vorherigen Linien auszurichten.



4.6 Leerzeichen und Einrückungen



4.6.1 Einrückung



Es wird immer eine leere Zeile eingefügt:



1. Zwischen aufeinanderfolgenden Mitgliedern oder Klasseninitialisierern: Felder, Konstruktoren, Methoden, verschachtelte Klassen, statische und dynamische Initialisierungsblöcke



  • Ausnahme: Eine leere Zeile zwischen zwei aufeinander folgenden Feldern (kein Code zwischen ihnen) ist optional. Leere Zeilen werden verwendet, um Felder bei Bedarf logisch zu gruppieren
  • Ausnahme: Leerzeilen zwischen Enum-Klassenkonstanten (siehe Abschnitt 4.8.1)


2. In Übereinstimmung mit anderen Abschnitten dieses Dokuments (z. B. Abschnitt 3 und Abschnitt 3.3) Die



leere Zeile kann auch durchgehend verwendet werden, um die Lesbarkeit des Codes zu verbessern, z. B. zwischen Ausdrücken, um Code in logischen Unterabschnitten zu organisieren. Eine leere Zeichenfolge vor dem ersten Mitglied einer Klasse oder einem Initialisierungsblock oder nach dem letzten Mitglied oder einem Initialisierungsblock einer Klasse wird nicht empfohlen, ist jedoch nicht verboten.



Mehrere aufeinanderfolgende Leerzeilen sind zulässig, aber nicht erforderlich oder werden empfohlen.



4.6.2 Leerzeichen



Abgesehen von den Anforderungen der Sprache selbst oder anderen Regeln dieses Dokuments sowie ohne Berücksichtigung von Literalen und Kommentaren (einschließlich Javadoc) können einzelne Leerzeichen aus der ASCII-Tabelle nur an den folgenden Stellen vorhanden sein:



1. Wenn Sie ein reserviertes Wort trennen, z. für oder fangen und eine öffnende Klammer "(", die folgt



2. Wenn Sie ein reserviertes Wort wie else oder catch trennen, und eine schließende geschweifte Klammer "}", die folgt



3. Vor jeder öffnenden geschweiften Klammer " {", Mit Ausnahme von zwei Situationen:



  • @SomeAnnotation ({a, b})
  • String [] [] x = {{"foo"}}; - Leerzeichen zwischen {{gemäß Abschnitt 8 unten nicht erforderlich


4. Auf beiden Seiten eines binären oder ternären Operators



Diese Regel gilt auch für die folgenden Operatoren:



  • kaufmännisches Und in spitzen Klammern: <T erweitert Foo & Bar>
  • ein Trennzeichen in einem catch-Block, das mehrere Ausnahmen enthält: catch (FooException | BarException e)
  • Doppelpunkt ":" in für jeden
  • Pfeil im Lambda-Ausdruck: (String str) -> str.length ()


Diese Regel gilt jedoch nicht für Operatoren:



  • Doppelter Doppelpunkt "::" der Referenzmethode, die als Object :: toString geschrieben ist
  • der Trennpunkt ".", der als object.toString () geschrieben wird


5. Nach ",:;" oder die schließende Klammer ")" beim Umwandeln in Typ



6. Auf beiden Seiten des doppelten Schrägstrichs "//" beim Erstellen eines Kommentars in derselben Codezeile. Hier sind mehrere Leerzeichen zulässig, aber nicht erforderlich.



7. Zwischen der Typdeklaration und dem Variablennamen:
List<String> list


8. Optional: In den Klammern des Array-Initialisierers sind sowohl

new int [] {5, 6} als auch new int [] {5, 6} gültig.



9. Zwischen der Typanmerkung und [] oder ...



Diese Regel erfordert kein Vorhandensein oder Fehlen von Leerzeichen in Anfang oder Ende einer Zeile; es gilt nur für Innenräume.



4.6.3 Eine horizontale Ausrichtung ist niemals erforderlich



Terminologie



Bei der horizontalen Ausrichtung wird in Ihrem Code eine unterschiedliche Anzahl zusätzlicher Leerzeichen hinzugefügt, damit bestimmte Elemente unter anderen Elementen aus der vorherigen Zeile angezeigt werden.



Diese Vorgehensweise ist zulässig, wird jedoch in diesem Handbuch nicht vorgeschrieben. Es ist auch nicht erforderlich, die Ausrichtung in den Teilen des Codes beizubehalten, in denen er bereits angewendet wurde.



Beispiel mit und ohne Ausrichtung:



private int x; // 
private Color color; //   

private int   x;      // ,     
private Color color;  //    


Die Ausrichtung verbessert die Lesbarkeit des Codes, führt jedoch zu Problemen bei der zukünftigen Pflege dieses Codes. Angenommen, Sie möchten nur eine Zeile ändern. Diese Änderung kann die Formatierung des zuvor akzeptierten Codes verzerren, was akzeptabel ist. Höchstwahrscheinlich wird der Programmierer (vielleicht Sie) damit beginnen, die Anzahl der Leerzeichen in benachbarten Zeilen anzupassen, was möglicherweise eine ganze Reihe von Korrekturen auslöst. Das Ändern einer Zeile kann (im schlimmsten Fall) eine „Druckwelle“ sinnloser Arbeit auslösen. Im besten Fall werden Informationen im Versionsverlauf verzerrt, die Lesbarkeit des Codes beeinträchtigt und Zusammenführungskonflikte verschärft.



4.7 Gruppierungsklammern werden empfohlen



Sie sollten Gruppierungsklammern nur weglassen, wenn der Autor des Codes und der Prüfer der Meinung sind, dass es keine vernünftige Wahrscheinlichkeit gibt, dass der Code ohne Klammern falsch interpretiert wird, und die Klammern das Lesen nicht erleichtern würden. Es gibt keinen Grund zu der Annahme, dass jeder, der den Code liest, die gesamte Rangfolge der Java-Operatoren gespeichert hat.



4.8 Sonderausführungen



4.8.1 Aufzählungsklassen



Nach jedem Komma, das auf eine Aufzählungskonstante folgt, ist ein Zeilenumbruch optional. Zusätzliche Leerzeilen (normalerweise nur eine) sind ebenfalls zulässig. Hier ist ein Beispiel für einen solchen Code:



private enum Answer {
  YES {
    @Override public String toString() {
      return "yes";
    }
  },

  NO,
  MAYBE
}


Der Code einer Aufzählungsklasse ohne Methoden und Kommentare, die ihre Konstanten beschreiben, kann als Array-Initialisierer dargestellt werden (siehe Abschnitt 4.8.3.1):



private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }


Da Aufzählungen Klassen sind, sollten alle anderen Regeln, die für Klassen gelten, für sie gelten.



4.8.2 Variablendeklarationen



4.8.2.1 Eine Variable pro Deklaration



Jede Variable (Feld oder lokal) wird jeweils nur einzeln deklariert: Deklarationen wie int a, b; werden nicht verwendet.



Ausnahme : Im Header einer for-Schleife sind mehrere Variablendeklarationen zulässig.



4.8.2.2 Deklarieren Sie Variablen, wenn Sie sie benötigen



Lokale Variablen müssen nicht zu Beginn eines Blocks oder einer Blockkonstruktion deklariert werden. Umgekehrt müssen lokale Variablen unmittelbar vor der Verwendung deklariert werden, um ihren Umfang zu minimieren. Normalerweise werden lokale Variablen zum Zeitpunkt der Deklaration oder unmittelbar danach initialisiert.



4.8.3 Arrays



4.8.3.1 Array-Initialisierer können "block" sein



Jedes Array kann so initialisiert werden, als wäre es ein Blockkonstrukt. Beispielsweise ist der gesamte folgende Code gültig (die Liste der Beispiele ist nicht vollständig):



new int[] {
  0, 1, 2, 3
}
                        
new int[] {
  0, 1,
  2, 3
}

new int[]
    {0, 1, 2, 3}

new int[] {
  0,
  1,
  2,
  3
}


4.8.3.2 Keine Array-Deklarationen im C-Stil



Die eckigen Klammern stehen nach dem Typ und nicht nach der Variablen: String [] args, nicht String args [].



4.8.4 Die switch-Anweisung



Terminologie



Eine oder mehrere Gruppen von Anweisungen befinden sich innerhalb eines Schalterblocks. Jede Gruppe besteht aus einer oder mehreren Beschriftungen (beide Fälle FOO: und Standard :), gefolgt von einer oder mehreren Anweisungen (oder im Fall der letzten Gruppe keiner oder mehreren).



4.8.4.1 Versatz



Wie bei jedem anderen Block ist der Inhalt des Schaltblocks um 2 Leerzeichen versetzt.



Nach der Beschriftung des Schalterblocks wird ein Zeilenumbruch ausgeführt, und der Versatz wird um 2 Leerzeichen erhöht, genau wie beim Öffnen des Blocks. Jedes nächste Etikett kehrt zum vorherigen Versatz zurück, wie beim Schließen eines Blocks.



4.8.4.2 Die Durchgangspassage wird kommentiert



Innerhalb eines Blocks wird jede Gruppe von Anweisungen entweder vorzeitig mit einem Schalter beendet (unter Verwendung von break, continue, return oder Auslösen einer Ausnahme) oder mit einem Kommentar markiert, um anzuzeigen, dass die Codeausführung in der nächsten Gruppe fortgesetzt wird oder fortgesetzt werden kann. Jeder Kommentar, der die Idee einer Durchgangspassage vermittelt (normalerweise // durchfallen), ist ausreichend. Dieser Kommentar ist in der letzten Gruppe des Schalterblocks nicht erforderlich. Beispiel:



switch (input) {
  case 1:
  case 2:
    prepareOneOrTwo();
    // fall through
  case 3:
    handleOneTwoOrThree();
    break;
  default:
    handleLargeNumber(input);
}


Bitte beachten Sie, dass der Kommentar nicht nach Fall 1 steht, sondern nur am Ende der Anweisungsgruppe.



4.8.4.3 Verwenden Sie immer die Standardeinstellung



Die switch-Anweisung muss die Standardbezeichnung enthalten, auch wenn kein Code enthalten ist.



Ausnahme : Ein Switch-Block für einen Aufzählungstyp verwendet möglicherweise nicht die Standardeinstellung, wenn er explizite Fälle enthält, die alle möglichen Werte dieses Typs abdecken. Auf diese Weise kann die IDE oder andere statische Analysetools eine Warnung ausgeben, dass einige Fälle nicht abgedeckt sind.



4.8.5 Anmerkungen



Anmerkungen, die auf eine Klasse, Methode oder einen Konstruktor angewendet werden, folgen unmittelbar nach dem Dokumentblock. Jede Anmerkung wird in einer eigenen Zeile angezeigt (dh eine Anmerkung pro Zeile). Diese Zeilenumbrüche sind keine Zeilenumbrüche (siehe Abschnitt 4.5), daher wird die Einrückungsstufe nicht erhöht. Beispiel:



@Override
@Nullable
public String getNameIfPresent() { ... }


Ausnahme : Eine einzelne Anmerkung ohne Parameter kann zusammen mit der ersten Signaturzeile angezeigt werden, zum Beispiel:



@Override public int hashCode() { ... }


Auf ein Feld angewendete Anmerkungen werden auch unmittelbar nach dem Dokumentblock angezeigt. In diesem Fall können jedoch mehrere (möglicherweise parametrisierte) Anmerkungen in einer einzelnen Zeile aufgelistet werden, z.



@Partial @Mock DataLoader loader;


Es gibt keine speziellen Regeln zum Formatieren von Anmerkungen für Parameter, lokale Variablen oder Typen.



4.8.6 Kommentare



Dieser Abschnitt ist Implementierungskommentaren gewidmet. Javadoc wird in Abschnitt 7 separat behandelt.



Vor jedem Zeilenumbruch kann eine beliebige Anzahl von Leerzeichen stehen, gefolgt von einem Implementierungskommentar. Dieser Kommentar macht die Zeile nicht leer.



4.8.6.1 Kommentarstil blockieren



Die Einrückungsstufe eines Blockkommentars entspricht der des umgebenden Codes. Blockkommentare können entweder / *… * / oder //… sein. Bei mehrzeiligen Kommentaren wie / *… * / müssen nachfolgende Zeilen mit einem * beginnen, das mit einem * aus der vorherigen Zeile ausgerichtet ist.




/*
 * This is          // And so           /* Or you can
 * okay.            // is this.          * even do this. */
 */


Kommentare sind nicht in Rechtecken eingeschlossen, die durch Sternchen oder andere Symbole dargestellt werden.



Verwenden Sie beim Schreiben mehrzeiliger Kommentare den Stil / * ... * /, wenn der automatische Code-Formatierer die Zeile nach Bedarf unterbrechen soll (im Stil von Absätzen). Die meisten Formatierer können dies nicht mit einzeiligen Kommentarblöcken tun // ...



4.8.7 Modifikatoren



Klassen- und Feldmodifikatoren werden, falls vorhanden, in der von der Java-Sprachspezifikation empfohlenen Reihenfolge angezeigt:



public protected private abstract default static final transient volatile synchronized native strictfp


4.8.8 Numerische Literale



Der lange Typ verwendet einen Großbuchstaben L, keinen Kleinbuchstaben (um nicht mit der Zahl 1 verwechselt zu werden). Zum Beispiel 300_000_000L anstelle von 300_000_000l.



5. Benennen



5.1 Allgemeine Regeln für alle Bezeichner



Bezeichner verwenden nur ASCII-Buchstaben und -Zahlen und in einigen unten angegebenen Fällen Unterstriche.



Somit stimmt jeder gültige Bezeichnername mit dem regulären Ausdruck \ w + überein (ein alphanumerisches Zeichen, das ein- oder mehrmals vorkommt).



Namen, die spezielle Suffixe oder Präfixe verwenden, wie z. B. name_, mName, s_name oder kName, entsprechen nicht dem Stil dieses Lernprogramms.



5.2 Regeln für verschiedene Arten von Bezeichnern



5.2.1 Paketnamen



Paketnamen müssen in Kleinbuchstaben ohne camelCase oder Unterstriche geschrieben werden.



Richtig: com.example.deepspace

Falsch: com.example.deepSpace oder com.example.deep_space



5.2.2 Klassennamen



Klassennamen werden im UpperCamelCase-Stil (großgeschriebener Anfangsbuchstabe) geschrieben.



Klassennamen sind normalerweise Substantive oder Nominalphrasen. Zum Beispiel Character oder ImmutableList.



Schnittstellennamen können auch Substantive oder Nominalphrasen sein (z. B. Liste), aber manchmal können sie auch Adjektive oder Adjektivkombinationen sein (z. B. Lesbar).



Es gibt keine spezifischen Regeln oder sogar gut etablierten Konventionen für die Benennung von Anmerkungstypen.



Testklassen haben einen Namen, der mit dem Namen der Klasse beginnt, die sie testen, und mit Test endet. Zum Beispiel HashTest oder HashIntegrationTest.



5.2.3 Methodennamen



Methodennamen werden im LowerCamelCase-Stil geschrieben.



Methodennamen sind normalerweise Verben oder Verbalphrasen. Zum Beispiel sendMessage oder stop.



Unterstriche können in JUnit-Testmethodennamen verwendet werden, um logische Komponenten im Namen zu trennen. Darüber hinaus ist jede Komponente im LowerCamelCase-Stil geschrieben. Das typische Muster ist:



<methodUnderTest>_<state>, , pop_emptyStack


Es gibt keinen einzigen richtigen Weg, um Testmethoden zu benennen.



5.2.4 Konstante Namen



Konstanten werden im CONSTANT_CASE-Stil benannt: Alle Buchstaben sind Großbuchstaben, wobei jedes Wort durch einen Unterstrich vom nächsten getrennt ist. Aber was genau ist eine Konstante?



Konstanten sind statische Endfelder, deren Inhalt unveränderlich ist, und Methoden, die keine sichtbaren Nebenwirkungen haben. Dies gilt für Grundelemente, Zeichenfolgen, unveränderliche Typen und unveränderliche Sammlungen unveränderlicher Typen. Wenn sich ein beobachtbarer Zustand eines Objekts ändern kann, ist dies keine Konstante. Eine einfache Absicht, ein Objekt niemals zu modifizieren, reicht nicht aus.



Beispiele:



// 
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);
static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }

//  
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final Set<String> mutableCollection = new HashSet<String>();
static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
static final ImmutableMap<String, SomeMutableType> mutableValues =
    ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};


Konstante Namen sind normalerweise Substantive oder Nominalphrasen.



5.2.5 Namen nicht konstanter Felder



Die Namen von Feldern, die keine Konstanten sind (statisch oder nicht), werden im LowerCamelCase-Stil geschrieben.



Die Namen solcher Felder sind normalerweise Substantive oder Nominalphrasen. Zum Beispiel computedValues ​​oder index.



5.2.6 Parameternamen



Parameternamen werden im LowerCamelCase-Stil geschrieben.



Einstellige Parameternamen sollten in öffentlichen Methoden vermieden werden.



5.2.7 Lokale Variablennamen



Lokale Variablennamen werden im LowerCamelCase-Stil geschrieben.



Obwohl sie endgültig und unveränderlich sind, werden lokale Variablen nicht als Konstanten betrachtet und sollten nicht im gleichen Stil wie Konstanten geschrieben werden.



5.2.8 Namen von Typvariablen



Jede Typvariable wird nach einem von zwei Stilen benannt:



  • Einzelner Großbuchstabe, auf den eine reguläre Zahl folgen kann (z. B. E, T, X, T2)
  • Ein Name in Form eines Klassennamens (siehe Abschnitt 5.2.2) gefolgt von einem Großbuchstaben T (Beispiele: RequestT, FooBarT).


5.3 Kamelstil (camelCase)



Manchmal gibt es mehrere Möglichkeiten, eine englische Phrase in einen Kamelstil umzuwandeln, z. B. bei Abkürzungen oder atypischen Ausdrücken wie „IPv6“ oder „iOS“.



Um die Vorhersagbarkeit zu verbessern, enthält dieses Handbuch das folgende (beispielhafte) Schema.



Beginnen Sie mit der ursprünglichen Form des Namens:



1. Konvertieren Sie die Phrase in reguläres ASCII und entfernen Sie alle Apostrophe. Zum Beispiel kann "Müllers Algorithmus" in "Müllers Algorithmus" konvertiert werden.



2. Teilen Sie das Ergebnis in Wörter, verwerfen Sie Leerzeichen und verbleibende Interpunktion (normalerweise Bindestriche):



  • Empfehlung: Wenn ein Wort bereits eine gemeinsame Form im üblichen „Kamel“ -Stil hat, teilen Sie es in seine Bestandteile auf (z. B. wird „AdWords“ in „Anzeigenwörter“ konvertiert). Beachten Sie, dass ein Wort wie „iOS“ nicht wirklich im Kamelstil ist. Es entspricht keinen Konventionen, daher gilt diese Empfehlung nicht.


3. Konvertieren Sie nun alles in Kleinbuchstaben (einschließlich Abkürzungen) und konvertieren Sie dann das erste Zeichen in Großbuchstaben:



  • ... in jedem Wort, um den UpperCamelCase-Stil zu erreichen, oder
  • ... in jedem Wort außer dem ersten, das den LowerCamelCase-Stil erreicht


4. Verketten



Sie abschließend alle Wörter zu einem einzigen Bezeichner. Beachten Sie, dass der Fall der ursprünglichen Wörter fast vollständig ignoriert wird.



Beispiele:

Ursprungsform Recht Falsch
"XML HTTP Anfrage" XmlHttpRequest XMLHTTPRequest
"Neukunden-ID" newCustomerId newCustomerID
"Innere Stoppuhr" innerStopwatch innerStopWatch
"Unterstützt IPv6 unter iOS?" unterstützt IPv6OnIos unterstützt IPv6OnIOS
"YouTube-Importeur" YouTubeImporter

YoutubeImporter *


* Erlaubt, aber nicht empfohlen.



Hinweis : Einige englische Wörter verwenden einen Bindestrich mehrdeutig: Beispielsweise sind sowohl "nicht leer" als auch "nicht leer" korrekt, sodass auch die Methodennamen checkNonempty und checkNonEmpty korrekt sind.



6. Programmierpraxis



6.1 Verwenden Sie immer die Annotation @Override



Die Methode ist immer dann mit der Anmerkung @Override gekennzeichnet, wenn sie tatsächlich überschrieben wird. Dies gilt sowohl für eine Methode einer untergeordneten Klasse, die eine Methode einer übergeordneten Klasse überschreibt, als auch für eine Schnittstellenmethode, die eine Methode einer Superschnittstelle überschreibt.



Ausnahme : Die Annotation kann weggelassen werden, wenn die übergeordnete Methode mit @Deprecated Annotation markiert ist.



6.2 Ignorieren Sie gefangene Ausnahmen nicht



Es kommt sehr selten vor, dass Sie in Reaktion auf eine abgefangene Ausnahme keine Maßnahmen ergreifen müssen (eine typische Lösung besteht darin, sie zu protokollieren oder, wenn dies als "unmöglich" eingestuft wird, die Ausnahme als AssertionError auszulösen).



Unten finden Sie ein Beispiel mit einem erläuternden Kommentar dazu, wann es wirklich angemessen ist, im catch-Block keine Maßnahmen zu ergreifen:



try {
  int i = Integer.parseInt(response);
  return handleNumericResponse(i);
} catch (NumberFormatException ok) {
  // it's not numeric; that's fine, just continue
}
return handleTextResponse(response);


Ausnahme : In Tests kann eine abgefangene Ausnahme ignoriert und nicht kommentiert werden, wenn der Testname erwartet wird oder wenn der Name mit erwartet beginnt. Das Folgende ist eine sehr verbreitete Redewendung, die zeigt, dass der zu testende Code eine Ausnahme vom erwarteten Typ auslöst, sodass hier keine Kommentare erforderlich sind:



try {
  emptyStack.pop();
  fail();
} catch (NoSuchElementException expected) {
}


6.3 Verwenden Sie für statische Elemente den Klassennamen



Es ist erforderlich, über den Klassennamen auf ein Mitglied einer statischen Klasse zuzugreifen und nicht über ein Klassenobjekt oder einen Ausdruck, der dieses Objekt zurückgibt:



Foo aFoo = ...;
Foo.aStaticMethod(); // 
aFoo.aStaticMethod(); // 
somethingThatYieldsAFoo().aStaticMethod(); //  


6.4 Verwenden Sie keine Finalizer



Es ist äußerst selten, dass Sie die Object.finalize-Methode überschreiben müssen.



Hinweis :



Tu das nicht. Wenn Sie es wirklich brauchen, lesen Sie zuerst Effective Java Item 7, vermeiden Sie Finalizer und verstehen Sie es gründlich.



7. Javadoc



7.1 Formatierung



7.1.1 Hauptformular



Die einfache Formatierung von Javadoc-Blöcken folgt diesem Beispiel:



/**
 * Multiple lines of Javadoc text are written here,
 * wrapped normally...
 */
public int method(String p1) { ... }


... oder in einer Zeile:



/** An especially short bit of Javadoc. */


Das einfache Formular ist immer anwendbar. Das einzeilige Formular kann angewendet werden, wenn der gesamte Javadoc-Block (einschließlich Kommentarmarkierungen) in eine Zeile passt. Beachten Sie, dass dies nur gilt, wenn der Block keine Tags wie @return enthält.



7.1.2 Absätze



Eine leere Zeile, dh eine Zeile, die nur ein ausgerichtetes führendes Sternchen (*) enthält, wird zwischen Absätzen und gegebenenfalls vor der Block-Tag-Gruppe angezeigt. Jeder Absatz außer dem ersten enthält ein <p> unmittelbar vor dem ersten Wort, ohne ein Leerzeichen danach.



7.1.3 Tags blockieren



Alle Block-Tags sind in dieser Reihenfolge: @param, @return, @throws, @deprecated, und diese vier Typen sind niemals mit leeren Beschreibungen vorhanden. Wenn ein Block-Tag nicht in eine Zeile passt, werden Fortsetzungszeilen um vier (oder mehr) Leerzeichen von @ eingerückt.



7.2 Letzter Ausschnitt



Jeder Javadoc-Block beginnt mit einem kurzen Zusammenfassungsausschnitt. Dieses Snippet ist sehr wichtig: Es ist der einzige Text, der in einem bestimmten Kontext angezeigt wird, z. B. Klassen- und Methodenindizes.



Dieses Snippet ist ein Substantiv oder eine Verbalphrase, kein vollständiger Satz. Es beginnt nicht mit A {@code Foo} ist ein ... oder Diese Methode gibt ... zurück und bildet auch keinen vollständigen positiven Satz wie Save the record. Diese Passage wird jedoch groß geschrieben und interpunktiert, als wäre es ein vollständiger Satz.



Hinweis : Es ist ein häufiger Fehler, einfache Javadoc-Dateien wie / ** @return the customer ID * / zu schreiben. Dies ist falsch und sollte auf / ** korrigiert werden. Gibt die Kunden-ID zurück. * /.



7.3 Wenn Javadoc angewendet wird



Javadoc ist in mindestens jeder öffentlichen Klasse und in jedem öffentlichen und geschützten Mitglied dieser Klasse vertreten, außer in einigen nachstehend beschriebenen Fällen.

Zusätzliches Javadoc kann vorhanden sein, wie in Abschnitt 7.3.4, Optionales Javadoc erläutert.



7.3.1 Ausnahme: Methoden, die sich selbst beschreiben



Javadoc ist optional für einfache und offensichtliche Methoden wie getFoo, wenn Sie wirklich nicht mehr als "Returns foo" sagen können.



Wichtig : Es ist unangemessen, auf diese Ausnahme zu verweisen, um das Auslassen relevanter Informationen zu rechtfertigen, die der allgemeine Leser möglicherweise benötigt.



Lassen Sie beispielsweise für eine Methode mit dem Namen getCanonicalName die Dokumentation nicht aus (mit der Begründung, dass der Methodenname nur / ** den kanonischen Namen zurückgibt. * /), Wenn die durchschnittliche Person, die den Code liest, möglicherweise nicht einmal ahnt, was der Begriff "kanonischer Name" bedeutet !



7.3.2 Ausnahme: Überschreiben

Javadoc begleitet nicht immer eine Methode, die eine Methode aus einer Superklasse (oder Superschnittstelle) überschreibt.



7.3.4 Optionales Javadoc



Andere Klassen und Mitglieder werden nach Bedarf oder Wunsch von Javadoc begleitet.



Immer wenn ein Implementierungskommentar verwendet wird, um den allgemeinen Zweck oder das Verhalten einer Klasse oder eines Mitglieds zu definieren, wird dieser Kommentar als Javadoc (mit / **) geschrieben.



Das optionale Javadoc muss nicht den Formatierungsregeln der Abschnitte 7.1.2, 7.1.3 und 7.2 entsprechen, obwohl dies natürlich empfohlen wird.



Diese Übersetzung ist auch in unserem Blog verfügbar .



All Articles