Suche…


Einführung

Der offizielle Oracle-Style-Guide für die Java-Programmiersprache ist ein Standard, der von Oracle-Entwicklern befolgt wird und von jedem anderen Java-Entwickler empfohlen wird. Es umfasst Dateinamen, Dateiorganisation, Einrückung, Kommentare, Deklarationen, Anweisungen, Leerzeichen, Namenskonventionen, Programmierpraktiken und enthält ein Codebeispiel.

Bemerkungen

  • Die obigen Beispiele folgen strikt dem neuen offiziellen Style Guide von Oracle. Sie werden also nicht subjektiv von den Autoren dieser Seite verfasst.

  • Der offizielle Style Guide wurde sorgfältig geschrieben, um rückwärtskompatibel mit dem ursprünglichen Style Guide und dem Großteil des Codes in freier Wildbahn zu sein.

  • Der offizielle Styleguide wurde von Brian Goetz (Java Language Architect) und Mark Reinhold (Chefarchitekt der Java-Plattform) einem Peer- Review unterzogen.

  • Die Beispiele sind nicht normativ; Sie möchten zwar die korrekte Formatierung des Codes veranschaulichen, es gibt jedoch andere Möglichkeiten, den Code richtig zu formatieren. Dies ist ein allgemeiner Grundsatz: Es gibt mehrere Möglichkeiten, den Code zu formatieren, wobei alle den offiziellen Richtlinien entsprechen.

Regeln der Namensgebung

Paketnamen

  • Die Paketnamen sollten alle ohne Unterstriche oder andere Sonderzeichen in Kleinbuchstaben geschrieben werden.
  • Paketnamen beginnen mit dem umgekehrten Berechtigungsbereich der Webadresse des Unternehmens des Entwicklers. Auf diesen Teil kann eine von der Projekt- / Programmstruktur abhängige Paketunterstruktur folgen.
  • Verwenden Sie keine Pluralform. Folgen Sie der Konvention der Standard-API, die zum Beispiel java.lang.annotation und nicht java.lang.annotations .
  • Beispiele: com.yourcompany.widget.button , com.yourcompany.core.api

Klassen-, Schnittstellen- und Aufzählungsnamen

  • Klassen- und Enumnamen sollten normalerweise Nomen sein.
  • Schnittstellennamen sollten in der Regel Substantive oder Adjektive sein, die auf ... enden.
  • Verwenden Sie die Groß- und Kleinschreibung mit dem ersten Buchstaben in jedem Wort (z. B. CamelCase ).
  • ^[AZ][a-zA-Z0-9]*$ den regulären Ausdruck ^[AZ][a-zA-Z0-9]*$ .
  • Verwenden Sie ganze Wörter und vermeiden Sie die Verwendung von Abkürzungen, es sei denn, die Abkürzung wird häufiger als die Langform verwendet.
  • Formatieren Sie eine Abkürzung als Wort, wenn sie Teil eines längeren Klassennamens ist.
  • Beispiele: ArrayList , BigInteger , ArrayIndexOutOfBoundsException , Iterable .

Methodennamen

Methodennamen sollten normalerweise Verben oder andere Beschreibungen von Aktionen sein

  • Sie sollten mit dem regulären Ausdruck ^[az][a-zA-Z0-9]*$ .
  • Verwenden Sie die Groß- und Kleinschreibung mit dem ersten Buchstaben.
  • Beispiele: toString , hashCode

Variablen

Variablennamen sollten in Groß- und Kleinschreibung mit dem ersten Buchstaben geschrieben werden

  • ^[az][a-zA-Z0-9]*$ den regulären Ausdruck ^[az][a-zA-Z0-9]*$
  • Weitere Empfehlung: Variablen
  • Beispiele: elements , currentIndex

Typvariablen

In einfachen Fällen, in denen nur wenige Typvariablen beteiligt sind, verwenden Sie einen einzelnen Großbuchstaben.

  • Passen Sie den regulären Ausdruck ^[AZ][0-9]?$
  • Wenn ein Buchstabe aussagekräftiger ist als ein anderer (z. B. K und V für Schlüssel und Werte in Karten oder R für einen Funktionsrückgabetyp), verwenden Sie diesen, andernfalls T
  • Verwenden Sie in komplexen Fällen, in denen Variablen mit einem Buchstaben verwirrend werden, längere Namen, die in Großbuchstaben geschrieben sind, und verwenden Sie einen Unterstrich ( _ ), um Wörter zu trennen.
  • Beispiele: T , V , SRC_VERTEX

Konstanten

Konstanten ( static final Endfelder, deren Inhalt unveränderlich ist, durch Sprachregeln oder durch Konventionen), sollten mit Großbuchstaben und Unterstrich ( _ ) benannt werden, um Wörter zu trennen.

  • ^[AZ][A-Z0-9]*(_[A-Z0-9]+)*$ den regulären Ausdruck ^[AZ][A-Z0-9]*(_[A-Z0-9]+)*$
  • Beispiele: BUFFER_SIZE , MAX_LEVEL

Andere Richtlinien zur Benennung

  • Vermeiden Sie das Ausblenden / Spiegeln von Methoden, Variablen und Typvariablen in äußeren Bereichen.
  • Lassen Sie die Ausführlichkeit des Namens von der Größe des Bereichs abhängen. (Verwenden Sie beispielsweise beschreibende Namen für Felder großer Klassen und Kurznamen für lokale kurzlebige Variablen.)
  • Wenn Sie öffentliche statische Member benennen, lassen Sie den Bezeichner selbstbeschreibend sein, wenn Sie der Meinung sind, dass er statisch importiert wird.
  • Weiterführende Literatur: Naming Section (im offiziellen Java Style Guide)

Quelle: Java-Style-Richtlinien von Oracle

Java-Quelldateien

  • Alle Zeilen müssen mit einem Zeilenvorschubzeichen (LF, ASCII-Wert 10) abgeschlossen werden und nicht beispielsweise CR oder CR + LF.

  • Am Ende einer Zeile befindet sich möglicherweise kein Leerzeichen.

  • Der Name einer Quelldatei muss mit dem Namen der enthaltenen Klasse, gefolgt von der Erweiterung .java , .java , auch für Dateien, die nur eine private .java enthalten. Dies gilt nicht für Dateien, die keine Klassendeklarationen enthalten, wie package-info.java .

Spezielle Charaktere

  • Außer LF ist das einzige Leerzeichen Leerzeichen (ASCII-Wert 32). Beachten Sie, dass dies bedeutet, dass andere Leerzeichen (z. B. Zeichenfolgen- und Zeichenliterale) in Escape-Form geschrieben werden müssen.

  • \' , \" , \\ , \t , \b , \r , \f und \n sollten gegenüber entsprechenden oktalen (zB \047 ) oder Unicode-Zeichen (zB \u0027 ) mit \u0027 bevorzugt werden.

  • Sollte es zu Testzwecken erforderlich sein, gegen die obigen Regeln zu verstoßen, sollte der Test die erforderliche Eingabe programmgesteuert generieren .

Paket deklaration

package com.example.my.package;

Die Paketdeklaration sollte nicht Zeilenumbrüche enthalten, unabhängig davon, ob sie die empfohlene maximale Zeilenlänge überschreitet.

Anweisungen importieren

// First java/javax packages
import java.util.ArrayList;
import javax.tools.JavaCompiler;

// Then third party libraries
import com.fasterxml.jackson.annotation.JsonProperty;

// Then project imports
import com.example.my.package.ClassA;
import com.example.my.package.ClassB;

// Then static imports (in the same order as above)
import static java.util.stream.Collectors.toList;
  • Importanweisungen sollten sortiert werden…

    • … In erster Linie durch nicht statische / statische Importe.
    • … Sekundär nach Paketursprung in folgender Reihenfolge
      • Java-Pakete
      • Javax-Pakete
      • externe Pakete (zB org.xml)
      • interne Pakete (zB com.sun)
    • … Tertiär nach Paket- und Klassenkennung in lexikographischer Reihenfolge
  • Importanweisungen sollten nicht in Zeilen umbrochen werden, unabhängig davon, ob sie die empfohlene maximale Länge einer Zeile überschreiten.

  • Es sollten keine ungenutzten Importe vorhanden sein.

Wildcard-Importe

  • Platzhalterimporte sollten im Allgemeinen nicht verwendet werden.
  • Beim Importieren einer großen Anzahl eng zusammengehöriger Klassen (z. B. beim Implementieren eines Besuchers über einen Baum mit Dutzenden verschiedener Knotenklassen) kann ein Platzhalterimport verwendet werden.
  • In jedem Fall sollte nicht mehr als ein Platzhalterimport pro Datei verwendet werden.

Klassenstruktur

Reihenfolge der Teilnehmer

Die Teilnehmer sollten wie folgt bestellt werden:

  1. Felder (in der Reihenfolge öffentlich, geschützt und privat)
  2. Konstrukteure
  3. Fabrikmethoden
  4. Andere Methoden (in der Reihenfolge öffentlich, geschützt und privat)

Das Sortieren von Feldern und Methoden hauptsächlich nach ihren Zugriffsmodifizierern oder Bezeichnern ist nicht erforderlich.

Hier ist ein Beispiel für diese Reihenfolge:

class Example {

    private int i;

    Example(int i) {
        this.i = i;
    }

    static Example getExample(int i) {
        return new Example(i);
    }

    @Override
    public String toString() {
        return "An example [" + i + "]";
    }

}

Gruppierung der Schüler

  • Verwandte Felder sollten zusammen gruppiert werden.
  • Ein verschachtelter Typ kann direkt vor seiner ersten Verwendung deklariert werden. Andernfalls sollte es vor den Feldern angegeben werden.
  • Konstruktoren und überladene Methoden sollten nach Funktionalität gruppiert und mit zunehmender Priorität geordnet werden. Dies impliziert, dass die Delegation zwischen diesen Konstrukten im Code nach unten fließt.
  • Konstruktoren sollten ohne andere Mitglieder dazwischen gruppiert werden.
  • Überladene Varianten einer Methode sollten ohne andere Mitglieder dazwischen gruppiert werden.

Modifikatoren

class ExampleClass {
    // Access modifiers first (don't do for instance "static public")
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

interface ExampleInterface {
    // Avoid 'public' and 'abstract' since they are implicit
    void sayHello();
}
  • Modifikatoren sollten in der folgenden Reihenfolge angegeben werden

    • Zugriffsmodifizierer ( public / private / protected )
    • abstract
    • static
    • final
    • transient
    • volatile
    • default
    • synchronized
    • native
    • strictfp
  • Modifikatoren sollten nicht ausgeschrieben werden, wenn sie implizit sind. Zum Beispiel sollten Schnittstellenmethoden weder als public noch als abstract deklariert werden, und geschachtelte Enums und Schnittstellen sollten nicht als statisch deklariert werden.

  • Methodenparameter und lokale Variablen sollten nicht als final deklariert werden, es sei denn, sie verbessern die Lesbarkeit oder dokumentieren eine tatsächliche Entwurfsentscheidung.

  • Felder sollten als final deklariert werden, es sei denn, es besteht ein zwingender Grund, sie veränderbar zu machen.

Vertiefung

  • Die Einrückungsebene besteht aus vier Leerzeichen .
  • Für die Einrückung dürfen nur Leerzeichen verwendet werden. Keine Registerkarten
  • Leere Zeilen dürfen nicht eingerückt werden. (Dies wird durch die Regel "Leerzeichen ohne Leerzeichen" impliziert.)
  • case Leitungen sollten mit vier Räumen und Aussagen im Fall eingerückt werden sollen , mit weiteren vier Leerzeichen eingerückt werden.
switch (var) {
    case TWO:
        setChoice("two");
        break;
    case THREE:
        setChoice("three");
        break;
    default:
        throw new IllegalArgumentException();
}

Richtlinien zum Einrücken von Fortsetzungszeilen finden Sie unter Wrapping-Anweisungen .

Anweisungen einwickeln

  • Quellcode und Kommentare sollten im Allgemeinen nicht mehr als 80 Zeichen pro Zeile und selten mehr als 100 Zeichen pro Zeile (einschließlich Einrückung) umfassen.

    Das Zeichenlimit muss von Fall zu Fall beurteilt werden. Was wirklich zählt, ist die semantische "Dichte" und Lesbarkeit der Linie. Durch das lange Versehen von Zeilen sind sie schwer lesbar. In ähnlicher Weise kann das Durchführen von "heroischen Versuchen", sie in 80 Säulen einzupassen, das Lesen schwer machen. Die hier skizzierte Flexibilität soll es den Entwicklern ermöglichen, diese Extreme zu vermeiden und die Nutzung von Monitor-Immobilien nicht zu maximieren.

  • URLs oder Beispielbefehle sollten nicht umbrochen werden.

// Ok even though it might exceed max line width when indented.
Error e = isTypeParam
        ? Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)
        : Errors.InvalidRepeatableAnnotationNotApplicableInContext(targetContainerType));

// Wrapping preferable
String pretty = Stream.of(args)
                      .map(Argument::prettyPrint)
                      .collectors(joining(", "));

// Too strict interpretation of max line width. Readability suffers.
Error e = isTypeParam
        ? Errors.InvalidRepeatableAnnotationNotApplicable(
                targetContainerType, on)
        : Errors.InvalidRepeatableAnnotationNotApplicableInContext(
                targetContainerType);

// Should be wrapped even though it fits within the character limit
String pretty = Stream.of(args).map(Argument::prettyPrint).collectors(joining(", "));
  • Ein Wrapping auf einem höheren syntaktischen Level wird dem Wrapping auf einem niedrigeren syntaktischen Level vorgezogen.

  • Es sollte höchstens eine Anweisung pro Zeile enthalten.

  • Eine Fortsetzungszeile sollte auf eine der folgenden vier Arten eingerückt werden

    • Variante 1 : Mit 8 zusätzlichen Leerzeichen relativ zur Einrückung der vorherigen Zeile.
    • Variante 2 : Mit 8 zusätzlichen Leerzeichen relativ zur Startspalte des umschlossenen Ausdrucks.
    • Variante 3 : An vorherigem Geschwisterausdruck ausgerichtet (solange klar ist, dass es sich um eine Fortsetzungszeile handelt)
    • Variante 4 : Ausgerichtet mit dem vorherigen Methodenaufruf in einem verketteten Ausdruck.

Wrapping Method Declarations

int someMethod(String aString,
               List<Integer> aList,
               Map<String, String> aMap,
               int anInt,
               long aLong,
               Set<Number> aSet,
               double aDouble) {
    …
}

int someMethod(String aString, List<Integer> aList,
        Map<String, String> aMap, int anInt, long aLong,
        double aDouble, long aLong) {
    …
}

int someMethod(String aString,
               List<Map<Integer, StringBuffer>> aListOfMaps,
               Map<String, String> aMap)
        throws IllegalArgumentException {
    …
}

int someMethod(String aString, List<Integer> aList,
        Map<String, String> aMap, int anInt)
                throws IllegalArgumentException {
    …
}
  • Methodendeklarationen können formatiert werden, indem die Argumente vertikal oder durch eine neue Zeile und +8 zusätzliche Leerzeichen aufgelistet werden
  • Wenn eine Throws-Klausel umbrochen werden soll, setzen Sie den Zeilenumbruch vor die Throws-Klausel und stellen Sie sicher, dass sie sich aus der Argumentliste heraushebt, entweder durch Einrücken von +8 relativ zur Funktionsdeklaration oder +8 relativ zur vorherigen Zeile.

Ausdrücke einpacken

  • Wenn sich eine Zeile der maximalen Zeichengrenze nähert, sollten Sie sie immer in mehrere Anweisungen / Ausdrücke unterteilen, anstatt die Zeile zu umbrechen.
  • Pause vor den Operatoren.
  • Pause vor dem. in verketteten Methodenaufrufen.
popupMsg("Inbox notification: You have "
        + newMsgs + " new messages");

// Don't! Looks like two arguments
popupMsg("Inbox notification: You have " +
         newMsgs + " new messages");

Whitespace

Vertikaler Whitespace

  • Eine einzelne Leerzeile sollte verwendet werden, um…

    • Paket deklaration
    • Klassenerklärungen
    • Konstrukteure
    • Methoden
    • Statische Initialisierer
    • Instanzinitialisierer
  • … Und kann verwendet werden, um logische Gruppen von zu trennen

    • Anweisungen importieren
    • Felder
    • Aussagen
  • Mehrere aufeinanderfolgende Leerzeilen sollten nur zum Trennen von Gruppen verwandter Mitglieder und nicht als Standardabstand zwischen Mitgliedern verwendet werden.

Horizontales Leerzeichen

  • Ein einzelner Raum sollte verwendet werden…

    • So trennen Sie Schlüsselwörter von benachbarten öffnenden oder schließenden Klammern und Klammern
    • Vor und nach allen binären Operatoren und Operator-ähnlichen Symbolen wie Pfeilen in Lambda-Ausdrücken und Doppelpunkt in erweiterten for-Schleifen (jedoch nicht vor dem Doppelpunkt eines Labels)
    • Nach // beginnt ein Kommentar.
    • Nach Kommas trennen Argumente und Semikolons die Teile einer for-Schleife.
    • Nach der schließenden Klammer eines Casts.
  • In Variablendeklarationen wird das Ausrichten von Typen und Variablen nicht empfohlen.

Variablendeklarationen

  • Eine Variable pro Deklaration (und höchstens eine Deklaration pro Zeile)
  • Eckige Klammern von Arrays sollten am Typ ( String[] args ) und nicht an der Variablen ( String args[] ) liegen.
  • Deklarieren Sie eine lokale Variable direkt vor ihrer ersten Verwendung und initialisieren Sie sie so nahe wie möglich an der Deklaration.

Anmerkungen

Deklarationsanmerkungen sollten in einer separaten Zeile von der kommentierten Deklaration stehen.

@SuppressWarnings("unchecked")
public T[] toArray(T[] typeHolder) {
    ...
}

Wenige oder kurze Anmerkungen, die eine einzeilige Methode kommentieren, können jedoch in derselben Zeile wie die Methode stehen, wenn dadurch die Lesbarkeit verbessert wird. Zum Beispiel kann man schreiben:

@Nullable String getName() { return name; }

Aus Gründen der Konsistenz und Lesbarkeit sollten entweder alle Anmerkungen in derselben Zeile oder jede Anmerkung in einer separaten Zeile stehen.

// Bad.
@Deprecated @SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
    ...
}

// Even worse.
@Deprecated @SafeVarargs
@CustomAnnotation public final Tuple<T> extend(T... elements) {
    ...
}

// Good.
@Deprecated
@SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
    ...
}

// Good.
@Deprecated @SafeVarargs @CustomAnnotation
public final Tuple<T> extend(T... elements) {
    ...
}

Lambda-Ausdrücke

Runnable r = () -> System.out.println("Hello World");

Supplier<String> c = () -> "Hello World";

// Collection::contains is a simple unary method and its behavior is
// clear from the context. A method reference is preferred here.
appendFilter(goodStrings::contains);

// A lambda expression is easier to understand than just tempMap::put in this case
trackTemperature((time, temp) -> tempMap.put(time, temp));
  • Expression-Lambdas werden gegenüber einzeiligen Block-Lambdas bevorzugt.
  • Methodenreferenzen sollten im Allgemeinen gegenüber Lambda-Ausdrücken bevorzugt werden.
  • Bei Methodenreferenzen für gebundene Instanzen oder bei Methoden mit mehr als eins kann ein Lambda-Ausdruck leichter verständlich und daher bevorzugt sein. Vor allem, wenn das Verhalten der Methode nicht aus dem Kontext ersichtlich ist.
  • Die Parametertypen sollten weggelassen werden, es sei denn, sie verbessern die Lesbarkeit.
  • Wenn sich ein Lambda-Ausdruck über mehrere Zeilen erstreckt, sollten Sie eine Methode erstellen.

Redundante Klammern

return flag ? "yes" : "no";

String cmp = (flag1 != flag2) ? "not equal" : "equal";

// Don't do this
return (flag ? "yes" : "no");
  • Redundante Gruppierungsklammern (dh Klammern, die die Auswertung nicht beeinflussen) können verwendet werden, wenn sie die Lesbarkeit verbessern.
  • Redundante Gruppierungsklammern sollten normalerweise in kürzeren Ausdrücken mit gemeinsamen Operatoren weggelassen werden, aber in längeren Ausdrücken oder Ausdrücken mit Operatoren, deren Vorrang und Assoziativität ohne Klammern unklar sind. Zu letzteren gehören ternäre Ausdrücke mit nicht-trivialen Bedingungen.
  • Der gesamte Ausdruck, der auf ein return Schlüsselwort folgt, darf nicht in Klammern stehen.

Literale

long l = 5432L;
int i = 0x123 + 0xABC;
byte b = 0b1010;
float f1 = 1 / 5432f;
float f2 = 0.123e4f;
double d1 = 1 / 5432d;  // or 1 / 5432.0
double d2 = 0x1.3p2;
  • long Literale sollten das Suffix Großbuchstabe L .
  • Hexadezimal-Literale sollten die Großbuchstaben A - F .
  • Alle anderen numerischen Präfixe, Infixe und Suffixe sollten aus Kleinbuchstaben bestehen.

Hosenträger

class Example {
    void method(boolean error) {
        if (error) {
            Log.error("Error occurred!");
            System.out.println("Error!");
        } else { // Use braces since the other block uses braces.
            System.out.println("No error");
        }
    }
}
  • Öffnende Klammern sollten am Ende der aktuellen Zeile und nicht in einer eigenen Zeile stehen.

  • Vor einer schließenden Klammer sollte eine neue Zeile stehen, es sei denn, der Block ist leer (siehe Kurzformen unten).

  • Klammern werden auch empfohlen, wenn die Sprache sie optional macht, z. B. einzeilige Wenn- und Schleifenkörper.

    • Wenn ein Block mehr als eine Zeile umfasst (einschließlich Kommentare), muss er geschweifte Klammern enthalten.
    • Wenn einer der Blöcke in einer if / else Anweisung geschweifte Klammern enthält, muss der andere Block ebenfalls.
    • Wenn der Block in einem umschließenden Block den letzten Platz erreicht, muss er geschweifte Klammern haben.
  • Die Schlüsselwörter else , catch und while in do…while Schleifen stehen in derselben Zeile wie die schließende Klammer des vorhergehenden Blocks.

Kurz Formen

enum Response { YES, NO, MAYBE }
public boolean isReference() { return true; }

Die obigen Empfehlungen sollen die Einheitlichkeit verbessern (und damit die Bekanntheit / Lesbarkeit erhöhen). In manchen Fällen sind „Kurzformen“, die von den obigen Richtlinien abweichen, genauso lesbar und können stattdessen verwendet werden. Diese Fälle umfassen beispielsweise einfache Aufzählungsdeklarationen und triviale Methoden und Lambda-Ausdrücke.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow