---
title: 'Alle Neuerungen von Java 8 über die Javadoc finden'
url: 'https://www.tutego.de/blog/javainsel/2013/11/alle-neuerungen-von-java-8-ber-die-javadoc-finden'
markdown: 'https://www.tutego.de/blog/javainsel/2013/11/alle-neuerungen-von-java-8-ber-die-javadoc-finden.md'
date: '2013-11-16'
description: 'Im folgenden Beispiel wollen wir ein kleines Doclet schreiben, das Klassen, Methoden und Konstruktoren ausgibt, die das Tag @since 1.8 (bzw. @since 8, was aber eigentlich falsch ist) tragen. So lässt sich leicht ermitteln, was in der Version Java 8 alles hinzugekommen ist. Doclets werden normalerwe…'
taxonomy:
  category:
    - Insel
    - 'Java 8'
---

# Alle Neuerungen von Java 8 über die Javadoc finden

![Illustration einer tropischen Insel mit Palmen und einem hohen Berg](https://www.tutego.de/blog/javainsel/user/themes/tutego/images/insel-cover.jpg)# Java Blog für Programmierer

[Java Blog für Programmierer](https://www.tutego.de/blog/javainsel/)

## Alle Neuerungen von Java 8 über die Javadoc finden

16.11.2013 · [Christian Ullenboom](https://www.tutego.de/blog/javainsel/author/admin/)

Im folgenden Beispiel wollen wir ein kleines Doclet schreiben, das Klassen, Methoden und Konstruktoren ausgibt, die das Tag @since 1.8 (bzw. @since 8, was aber eigentlich falsch ist) tragen. So lässt sich leicht ermitteln, was in der Version Java 8 alles hinzugekommen ist. Doclets werden normalerweise von der Kommandozeile aufgerufen und dem javadoc-Tool übergeben. Unser Programm vereinfacht das, indem es direkt das Tool über Java mit dem passenden Parameter aufruft. tools.jar muss dafür im Klassenpfad sein und die Dokumentation ausgepackt am angegeben Ort.

```java

package com.tutego.tools.javadoc;

import java.util.*;
import java.util.function.Predicate;
import com.sun.javadoc.*;
import com.sun.tools.javadoc.Main;

public class SinceJava8FinderDoclet {

  public static boolean start( RootDoc root ) {
    for ( ClassDoc clazz : root.classes() )
      processClass( clazz );
    return true;
  }

  private static void processClass( ClassDoc clazz ) {
    Predicate isJava18 = tag -> tag.text().equals( "8" ) || tag.text().equals( "1.8" );

    if ( Arrays.stream( clazz.tags( "since" ) ).anyMatch( isJava18 ) )
      System.out.printf( "Neuer Typ %s%n", clazz );

    for ( MethodDoc method : clazz.methods() )
      if ( Arrays.stream( method.tags( "since" ) ).anyMatch( isJava18 ) )
        System.out.printf( "Neue Methode %s%n", method );

    for ( ConstructorDoc constructor : clazz.constructors() )
      if ( Arrays.stream( constructor.tags( "since" ) ).anyMatch( isJava18 ) )
        System.out.printf( "Neuer Konstruktor %s%n", constructor );

    for ( FieldDoc field : clazz.fields() )
      if ( Arrays.stream( field.tags( "since" ) ).anyMatch( isJava18 ) )
        System.out.printf( "Neues Attribut %s%n", field );
  }

  public static void main( String[] args ) {
    String[] params = {
        "-quiet", "-XDignore.symbol.file",
        "-doclet", SinceJava8FinderDoclet.class.getName(),
        "-sourcepath", "C:/Program Files/Java/jdk1.8.0/src/",
//        "java.lang",  // Nur java.lang
        "-subpackages", "java:javax"  // Alles rekursiv unter java.* und javax.*
    };
    Main.execute( params );
  }
}
```

Unsere main(`String`\[\])-Methode ruft das JDK-Doclet-Programm über `Main`.execute(`String`\[\]) auf und übergibt die eigene Doclet-Klasse per Parameter – die Argumente von execute(`String`\[\]) erinnern an die Kommandozeilenparameter. Das Doclet-Hauptprogramm wiederum ruft unsere `start(RootDoc root)`-Methode auf – das Gleiche würde auch passieren, wenn das Doclet von außen über javadoc aufgerufen würde. Unser `start(RootDoc)` läuft über alle ermittelten Typen und übergibt zum Abarbeiten der Innereien die Verantwortung an `processClass(ClassDoc)`. Die Metadaten kommen dabei über diverse XXXDoc-Typen. Ein Precidate zieht den Tag-Test heraus, ein weiterer Einsatz der neuen Java 8 Streams würde das Programm nicht übersichtlicher machen.

Das Programm nutzt ein paar Tricks, um die Ausgabe auf das Wesentliche zu konzentrieren. Der Schalter –quit schaltet den üblichen Ladestatus, der zu Ausgaben wie

Loading source files for package `java.lang`…

Loading source files for package `java.applet`…

Loading source files for package `java.awt`…

führt ab.

Der Schalter -XDignore.symbol.file wiederum unterdrückt Meldungen wie diese hier:

C:\\…\\src\\java\\lang\\`Class`.java:57: warning: `Unsafe` is internal proprietary API and may be removed in a future release

```java
import sun.misc.Unsafe;
```

^

Die Meldungen landen auf dem System.err-Kanal, sodass sie sich auch mit `System.setErr(…)` in einem ausgabeverwerfenden Strom geschickt werden können um sie zu unterdrücken.

Kategorien: [Insel](https://www.tutego.de/blog/javainsel/category/insel/), [Java 8](https://www.tutego.de/blog/javainsel/category/java-8/)

[← Alle Beiträge](https://www.tutego.de/blog/javainsel/)

---

## Navigation

- Previous: [Offtopic: Unterstützt Ärzte ohne Grenzen …](https://www.tutego.de/blog/javainsel/2013/11/offtopic-untersttzt-rzte-ohne-grenzen.md)
- Next: [Der Array-Index beginnt bei 0. Schon immer so?](https://www.tutego.de/blog/javainsel/2013/11/der-array-index-beginnt-bei-0-schon-immer-so.md)
