Mittwoch, 29. April 2009

@SuppressWarnings("unchecked")

Seit Version 5.0 kennt Java das Konzept der Generics, mit denen u.a. Kollektionen mit Typen parametrisiert und typsicherer gemacht werden können.

Leider lassen sich damit nicht alle Stellen perfekt absichern – insbesondere bei Hibernate bzw. JPA wird man beim Ausführen von Abfragen (Queries) immer wieder auf "Type safety"-Compiler-Warnungen stoßen:

An sich ist das kein Problem, denn mit der bestehenden API gibt es für den Compiler keine sinnvolle Möglichkeit, vom Query-String auf den Ergebnis-Typ zu schließen. Und Entwicklungsumgebungen wie Eclipse bieten die einfache Lösung an, diese unumgängliche Warnung mit der @SuppressWarnings-Annotation zu unterdrücken.

Nur leider schreibt Eclipse die Annotation immer vor die umgebende Methode, was alle weiteren – vielleicht wichtigen – Typ-Warnungen in der Methode ebenfalls unterdrückt:
@SuppressWarnings("unchecked")
public List<Benutzer> findAllBenutzer() {
Query q = session.createQuery("from Benutzer");
return q.list();
}
Das muss nicht sein! Sehen wir uns dazu den Quelltext der @SuppressWarnings-Annotation an:
@Target({TYPE, FIELD, METHOD, PARAMETER,
CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
LOCAL_VARIABLE bedeutet, dass wir die Annotation auch an eine lokale Variablendeklaration schreiben dürfen. Wenn wir also in der Methode eine temporäre Variable einführen, können wir das Unterdrücken der Warnung auf die eine relevante Zeile beschränken:
public List<Benutzer> findAllBenutzer() {
Query q = session.createQuery("from Benutzer");

@SuppressWarnings("unchecked")
List<Benutzer> alle = q.list();

return alle;
}
Für die JPA-Query-Methoden getResultList() und getSingleResult() gilt dies entsprechend.

1 Kommentar:

  1. Was vielleicht nicht direkt ersichtlich ist, dass dies sogar innerhalb einer for-Anweisung möglich ist:

    for (@SuppressWarnings("unchecked") Map rowMap : retList) {
    String s = (String) rowMap.get("viewtext");
    sb.append(s);
    }

    AntwortenLöschen