Sinn & Unsinn von {@inheritDoc}

Posted byChristian Moser Posted on13. December 2010 Comments2

Ich wurde schon des öfteren nach code-reviews darauf angesprochen, wieso ich bei meinen überschriebenen Methoden nicht immer {@inheritDoc}  im javadoc deklariere. Ich halte dieses Vorgehen bei 90% der Fälle als überflüssig und unübersichtlich. Um dies zu erläutern habe ich ein paar javadoc Tests durchgeführt…

Es wurden die Klassen ParentClass und ChildClass erstellt, wobei ChildClass von ParentClass erbt und die Methode “methodToOverride()” überschreibt.

Gezeigt werden code-Schnipsel aus ChildClass und dem entsprechend generierten Javadoc.

Methode überschrieben ohne Javadoc

public void methodToOverride() {
    System.out.println("do something...");
}

 

Wird kein Javadoc angegeben, so wird die Beschreibung der überschriebenen Methode automatisch referenziert. Fügt man allerdings einen Kommentar hinzu, wird das Javadoc wie folgt generiert:

Methode überschrieben mit Javadoc

/**
 * Javadoc of overriden method
 */
 public void methodToOverride() {
     System.out.println("do something...");
 }

 

Nun ist das Javadoc der überschriebenen Methode aus der Klasse ParentClass nicht mehr direkt ersichtlich, sondern wird durch den passenderen Kommentar ersetzt.

Methode überschrieben ohne Javadoc mit {@inheritDoc}

/**
 * {@inheritDoc }
 */
 public void methodToOverride() {
     // call overriden method
     super.methodToOverride();
 }

 

Wird auf einen Kommentar verzichtet und wird wie leider des öfteren nur {@inheritDoc} angegeben, so hat man ein ähnliches, wenn nicht schlechteres Resultat, wie wenn man kein javadoc schreibt! Der Kommentar wird 1:1 kopiert und die Information welche Methode das ursprüngliche javadoc beinhaltet ist verloren. Damit wird der Quellcode unnötig aufgeblasen und Informationen verschenkt.

Methode überschrieben mit Javadoc und {@inheritDoc}

/**
 * {@inheritDoc }
 * Javadoc of overriden method
 */
 public void methodToOverride() {
     System.out.println("do something...");
     //and call overriden method
     super.methodToOverride();
 }

 

Im Javadoc ist ersichtlich, dass der Kommentar aus der Beispiel-Methode (Javadoc of overriden method) am Ende angefügt wurde.

Der eigentliche Sinn von {@inheritDoc} liegt darin den Kommentar der überschriebenen Methode aus der parent Klasse wiederzuverwenden und mit dem der child Klasse zu ergänzen. Das Tag ist somit ein simpler Platzhalter, welcher nur Sinn macht, wenn die Methode wie im gezeigten Beispiel teilweise überschrieben wird. Dies ist allerdings “bad practice” und sollte wenn möglich vermieden werden, da dies den code sehr verstrickt und kompliziert macht. Desweiteren ist durch das Setzen des leeren Tags später im Javadoc nicht mehr klar ersichtlich, zu welcher Methode der Kommentar ursprünglich verfasst wurde. (siehe 1. Beispiel: “Description copied from class: ParentClass”)

Methode überschrieben mit Javadoc und @Override

 

/**
 * Javadoc of overriden method
 */
 @Override
 public void methodToOverride() {
    System.out.println("do something else!");
 }

 

Ab Java 1.5 sollte @Override verwendet werden um überschriebene Methoden klar zu kennzeichnen.

Methode überschrieben ohne Javadoc und @Override

@Override
public void methodToOverride() {
   System.out.println("do something else!");
}

 

Die annotation hat aber keinen Einfluss auf die Generierung des Javadocs wie man in diesem Beispiel sehen kann. Wurde kein Kommentar verfasst, so wird dies signalisiert und derjenige der parent Methode angezeigt wie in Beispiel 1.

Dieses Vorgehen ist zur Kennzeichnungs überschriebener Methoden im Vergleich zu @inheritDoc viel kompakter und man verliert keine Informationen darüber, zu welcher Methode der Kommentar ursprünglich verfasst wurde. Deshalb sollte der Einsatz von @inheritDoc nur beschränkt in Betracht gezogen werden. Desweiteren werden die @Override annotations bei einigen IDE’s deutlich hervorgehoben um eine noch bessere Übersicht zu gewähren und um zusätzliche Funktionen bereitzustellen.

Weiterführende Links

Automatic Copying of Method Comments:

http://download.oracle.com/javase/1.5.0/docs/tooldocs/windows/javadoc.html

Category

2 People reacted on this

  1. (+1) Noch interessanter wird, wenn man bedenkt, dass die Mechanismen für main description, @return, @param und @throws unabhängig sind. Annotiert man eine Methode also Java Doc einer Methode mit {@inheritDoc }, so wird nur die main description explizit geerbt. Die weiteren Parameter jedoch implizit.

  2. Guten Morgen Chris

    Ich musste heute Morgen schmunzeln, als ich deinen Blogeintrag gelesen habe! 🙂

    Diese Thematik wird übrigens auch im “Algorithm for Inheriting Method Descriptions” beschrieben.

    If a method does not have a doc comment, Javadoc searches for an applicable comment using the following algorithm, which is designed to find the most specific applicable doc comment, giving preference to interfaces over superclasses:

    1. Look in each directly implemented (or extended) interface in the order they appear following the word implements (or extends) in the method declaration. Use the first doc comment found for this method.

    2. If step 1 failed to find a doc comment, recursively apply this entire algorithm to each directly implemented (or extended) interface, in the same order they were examined in step 1.

    3. If step 2 failed to find a doc comment and this is a class other than Object (not an interface):
    If the superclass has a doc comment for this method, use it.
    If step 3a failed to find a doc comment, recursively apply this entire algorithm to the superclass.

    Weitere Informationen findest du bei Oracle…

    Gruss Fabio

Comments are closed.