07.05 Code Conventions

Bis auf Schlüsselwörter und allgemeine Syntax-Elemente wie z. B. den Punkt oder geschweifte Klammern gibt es in Java keine verpflichtenden Vorschriften, wie Ihr Programm aussehen muss. Allerdings sollte Ihr Code dennoch gut lesbar sein. Sun hat deshalb so genannte Code Conventions veröffentlicht, in denen Richtlinien beschrieben werden, wie Ihr Code formatiert sein sollte. Siehe hierzu auch Kapitel 01.04.03 Code-Formatierung.

Eines vorneweg: Es zwingt Sie niemand Ihren Code genau an die Vorgaben der Code Conventions von Sun anzupassen. Auch das Java Blog Buch macht das nicht exakt. Sie sollten sich aber zumindest einen ebenfalls gut lesbaren Stil angewöhnen. Gerne können Sie sich hierbei auch von ähnlichen Sprachen, die Sie bereits beherrschen, inspirieren lassen.

Der Sinn von Code Conventions

Code Conventions sind für die Lesbarkeit des Sourcecodes sehr wichtig. Warum der Sourcecode gut lesbar gehalten werden sollte? Weil ein Großteil der Kosten einer Software durch deren Wartung entsteht, ein Programm meistens von mehreren, unterschiedlichen Programmierern entwickelt wird, oder wenn der Code von einem Produkt mit verkauft wird, es wichtig ist, dass der Empfänger auch etwas mit dem Code anfangen kann.

Aufbau eines Java-Files

Sie sollten Ihre Klasse strukturiert aufbauen und unterschiedliche Bereiche durch Leerzeilen separieren. Diese Bereiche können optional mit entsprechenden Kommentaren gekennzeichnet werden. Vermeiden Sie Source-Files, die länger als 2000 Zeilen sind.

Jede Datei sollte genau eine einzige öffentliche Klasse oder Interface beinhalten. Sollten Sie private Klassen und Interfaces benötigen, die mit einer öffentlichen Klasse in Verbindung gebracht werden können, können Sie diese unterhalb der öffentlichen Klasse in die gleiche Datei packen.

Beginnen Sie Ihre Klassendefinition mit einem einleitenden Kommentar (siehe Kapitel 07.04.03 javadoc – Klassen dokumentieren). Anschließend kommt die Definition des Packages gefolgt von den benötigten imports. Bei der abschließenden Deklaration Ihrer Klasse oder Ihres Interfaces sollten Sie folgende Reihenfolge einhalten:

1 Klassen/Interface Dokumentation-Kommentare Siehe Kapitel 07.04.03 javadoc – Klassen dokumentieren.
2 Klassen/Interface-Kopf  
3 Erweiterter Kommentar zur Implementierung (optional) Enthält Informationen, die nicht in Punkt 1 benötigt/gepasst haben.
4 Klassen-Variablen Zuerst public, protected und zum Schluss private.
5 Objekt-Variablen Zuerst public, protected und zum Schluss private.
6 Konstruktoren  
7 Methoden Methoden sollten nicht nach Ihrer Sichtbarkeit, sondern nach Ihrer Funktionalität gruppiert werden, so dass das Lesen und Verstehen des Codes leichter wird.

Einrückungen

Zum Einrücken Ihres Codes sollten generell vier Leerzeichen verwendet werden, ein Tab ist acht Leerzeichen lang. Es bleibt Ihnen überlassen, ob Sie zum Einrücken Leerzeichen oder Tabs verwenden. Beachten Sie aber, dass Zeilen nie länger als 80 Zeichen seien sollten. Um solche langen Zeilen zu vermeiden, sollten Sie ggf. an bestimmten Punkten eine neue Zeile beginnen:

  • Zeilenumbrüche nach Kommata
  • Zeilenumbrüche vor Operatoren
  • Bevorzugen Sie high-level Umbrüche vor low-level Umbrüchen (Beispiel siehe unten)
  • Die neue Zeile sollte exakt unter dem Anfang des Ausdrucks aus der darüber liegenden Zeile beginnen
  • Falls diese Regeln zu Verwirrungen führen können, dürfen auch acht Leerzeichen zur Einrückung verwendet werden.

Methoden-Aufrufe

function(longExpression1, longExpression2, longExpression3,
         longExpression4, longExpression5);

var = function1(longExpression1,
                function2(longExpression2,
                          longExpression3));

Arithmetische Ausdrücke

longName1 = longName2 * (longName3 + longName4 - longName5)
             + 4 * longname6; // Gut

longName1 = longName2 * (longName3 + longName4
                         - longName5) + 4 * longname6; // schlecht

Methoden-Deklaration umbrechen

// Normale Einrückung
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
           Object andStillAnother) {
}
// Acht Leerzeichen Einrückung um tiefe Strukturen zu vermeiden
private static synchronized horkingLongMethodName(int anArg,
        Object anotherArg, String yetAnotherArg,
        Object andStillAnother) {
...
}

If-Anweisungen

// Besser acht-Leerzeichen als vier verwenden
if ((condition1 && condition2)
    || (condition3 && condition4)
    ||!(condition5 && condition6)) { // ungünstiger Umbruch, führt dazu,
    doSomethingAboutIt();            // dass diese Zeile leicht übersehen wird
}
// Besserer Umbruch
if ((condition1 && condition2)
        || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    doSomethingAboutIt();
}
// oder so
if ((condition1 && condition2) || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    doSomethingAboutIt();
}

Tertiäre Ausdrücke

alpha = (aLongBooleanExpression) ? beta : gamma;
alpha = (aLongBooleanExpression) ? beta
                                 : gamma;
alpha = (aLongBooleanExpression)
        ? beta
        : gamma;

Deklarationen

Sie sollten es vermeiden mehrere Variablen in einer Zeile zu deklarieren. Dieser Weg

int var;
int var2;
// auch in Ordnung:
int      alle;
long     attribute;
Object   gehoeren;
String   irgendwie;
byte     zusammen;

ist also diesem hier

int var, var2;

vorzuziehen. Was Sie aber auf keinen Fall machen sollten, ist die Deklaration von Variablen und Methoden oder von unterschiedlichen Datentypen in nur einer Zeile.

int aVar, getAVar(); // Falsch
int bvar, bvararray[]; // Falsch

Deklarieren Sie Ihre Variablen direkt am Anfang eines Blocks, also direkt nach der geöffneten, geschweiften Klammer und nicht erst, wenn Sie die Variable auch benötigen. Alles andere ist verwirrend und nur schwer lesbar. Gleichzeitig (zur Deklaration) sollten Sie Ihre Variablen nach Möglichkeit auch sofort initialisieren. Es sei denn, Sie müssen die Werte der Variablen zuerst berechnen.

Bei der Deklaration von Klassen und Interfaces sollte die geöffnete Klammer einer Parameterliste direkt an den Methodennamen angehängt werden. Die geöffnete, geschweifte Klammer sollte in die selbe Zeile wie die Deklaration geschrieben werden, die abschließende, geschweifte Klammer in eine separate Zeile. Methoden werden durch eine Leerzeile voneinander getrennt.

public class Sample extends Object {
  int ivar1;
  int ivar2;

  public Sample(int i, int j) {
    this.ivar1 = i;
    this.ivar2 = j;
  }

  private int emptyMethod() {}

  private void anOtherEmptyMethod() {}
}

Statements

Jede Zeile sollte genau einen Befehl enthalten. Sie sollten es also vermeiden mehrere Befehle durch ein Semikolon getrennt in eine Zeile zu schreiben. Schon gar nicht sollten Sie mehrere Befehle durch Kommata-Separierung gruppieren.

argv++; argc--; // Falsch
if (err) {
  Format.print(System.out, “error”), exit(1); // Ganz Falsch
}
  • In return-Statements sollten keine runden Klammern vorkommen, es sei denn, dass diese den Code besser lesbar machen.
  • If-Statements enthalten immer geschweifte Klammern. Es sollte vermieden werden auf diese Klammern zu verzichten. Bei verketteten Anweisungen wird die nächste „Kette“ an die vorhergehende „angehängt“:
if (anweisung) {
  // mach was
} else if (anweisung2) {
  // mach was anderes
} else {
  // mach was komplett anderes
}
  • Der Kopf einer for-Schleife endet immer mit der geschweiften Klammer. Das Ende der Schleife wird mit einer geschweiften Klammer in einer separaten Zeile angedeutet. Sollte die Schleife nur zählen und ansonsten keine Aktionen ausführen, können Sie die geschweiften Klammern auch komplett weglassen und durch ein Semikolon ersetzen (selbes gilt für die while-Schleife). Versuchen Sie es zu vermeiden mehr als drei Variablen direkt im Kopf der Schleife zu initialisieren.
  • Eine do-while-Schleife sollte so aussehen:
do {
  machWas();
} while (anweisung);
  • Bei switch-case-Anweisung sollten Sie immer eine default-Klausel einsetzen. Falls Sie bei einem case kein break verwenden, setzen Sie wenigstens an diese Stelle einen Kommentar.
switch (bedingung) {
case 1:
  statements;
  /* kein break */
case 2:
  statements;
  break;
case 3:
  statements;
  break;
default:
  statements;
  break;
}
  • Der try-catch-Block ist so wie der if-else if-else-Block aufgebaut.

White-Space

White-Space ist wichtig zur besseren Lesbarkeit von Code. Verwenden Sie ihn deshalb sinnvoll. Dies könnte z. B. so aussehen:

  • Zwei Leerzeilen benutzen:
  • Zwischen logischen Abschnitten im Code
  • Zwischen Klassen und Interface Deklarationen
  • Eine Leerzeile benutzen:
  • Zwischen Methoden
  • Zwischen lokalen Variablen in einer Methode und dem ersten Befehl
  • Vor Block- und Einzelzeilen-Kommentaren (siehe Kapitel 07.04.03 javadoc – Klassen dokumentieren)
  • Zwischen logischen Bereichen in einer Methode um die Lesbarkeit zu erhöhen
  • Leerzeichen benutzen:
  • Vor runden Klammern, die auf ein Schlüsselwort (aber nicht auf eine Methode) folgen
  • Nach Kommata in Argument-Listen
  • Zwischen allen Operatoren, außer dem Punkt (.)
  • Nach den Semikola im Kopf einer for-Schleife
  • Bei einem Casting nach den Typen, in welchen gecastet werden soll

Naming Conventions

Naming conventions sind die Richtlinien, wie Attribute, Klassen, … benannt werden sollten. Diese zu beachten wird von den meisten Programmieren als sehr wichtig angesehen. Es wird Sie vermutlich nie jemand ansprechen, wenn Sie eine solche If-Anweisung schreiben

if (bedingung)
{
  // mach was
}

, sehr wohl aber, wenn Ihre Klasse so aussieht:

public class mysuperclass {

  private int A;

  public int Geta() {
    return this.A;
  }
}

Deshalb halten Sie sich bitte an folgende Richtlinien:

Typ Regel Beispiel
Klassen und Interfaces Klassennamen sollten Nomen sein und in der Einzahl stehen. Sie beginnen mit einem großen Buchstaben und enthalten für jedes neue Wort im Namen der Klasse einen weiteren, großen Buchstaben (mixed case). Weit verbreitete Abkürzungen (wie HTML, XML oder UML) dürfen verwendet werden. class Person;
class DatenbankVerbindung;
interface Heizbar
Methoden Sie sollten Verben sein und beginnen immer mit einem kleinen Buchstaben. Jedes weitere Wort im Methodennamen fängt mit einem großen Buchstaben an. public void machWasTolles();
pubilc void starten();
public Object getAnObject();
Variablen Aussagekräftig und mit identischem Aufbau wie Methoden. Der Name von temporären Variablen (z. B. in einer for-Schleife) muss nicht zwingend aussagekräftig sein. Hierfür bieten sich die Bezeichnungen i, j, k, m und n für Integer-Werte, und die Bezeichnungen c, d und e für Characters an. for (int i = 0; i < 10; i++); Object anObject;
Konstanten Konstanten sollten alle komplett in Großbuchstaben verfasst werden. Einzelne Wörter in den Konstanten werden durch einen underscore (_) voneinander getrennt. int DEUTSCHLAND = 1;
int FRANKREICH = 2;
int USA = 3;
int EINWOHNER_DEUTSCHLAND = 80000000;
int A_VERY_COMPLEX_CONSTANT = 123;

Beachten Sie auch, dass Sie immer aussagekräftige Bezeichnungen verwenden.

Weitere Hinweise

Ebenfalls wichtig ist die Formatierung von Kommentaren. Diese wurde aber bereits besprochen, so dass an dieser Stelle keine Wiederholung mehr notwendig ist. Beachten Sie deshalb auch noch das Kapitel 07.04.03 javadoc - Klassen dokumentieren.

Sie finden die genaue, englische Originalspezifikation unter http://java.sun.com/docs/codeconv/.

One Reply to “07.05 Code Conventions”

  1. Pingback: Anonymous

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.