Jackson: Deserialisierung eines Objekt-Arrays in Java im Jahr 2025 — Leitfaden für Profis

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum jeder Java-Entwickler diesen Trick kennen sollte



Stellen Sie sich vor: Sie erhalten ein JSON vom Server, darin Dutzende gleichartiger Objekte. Kunden, Produkte, Logs – egal. Sie nehmen ObjectMapper, schreiben readValue(json, MyClass[].class) – und alles funktioniert. Einen Monat später stürzt der Code mit ClassCastException ab, weil jemand das Array durch ein List ersetzt hat. Kommt Ihnen bekannt vor?



Die Frage „How to use Jackson to deserialise an array of objects“ auf Stack Overflow hat Zehntausende von Aufrufen. Und das ist kein Zufall: Die Deserialisierung eines Objekt-Arrays in Java ist eine dieser Aufgaben, die einfach erscheinen, bis man auf Generics und Type Erasure stößt. Im Jahr 2025 bleibt Jackson der De-facto-Standard für die Arbeit mit JSON, aber die Best Practices haben sich geändert. In diesem Artikel behandeln wir nicht nur grundlegende Ansätze, sondern auch moderne Techniken, die Sie vor Kopfschmerzen bewahren.



Grundlegender Ansatz: Array oder Liste?



Der einfachste Weg ist die Verwendung eines Arrays. Jackson versteht perfekt, dass MyClass[].class ein Objekt-Array ist:



ObjectMapper mapper = new ObjectMapper();String json = "[{\\"id\\":1,\\"name\\":\\"Alice\\"},{\\"id\\":2,\\"name\\":\\"Bob\\"}]";MyClass[] array = mapper.readValue(json, MyClass[].class);


Funktioniert es? Ja. Aber dieser Ansatz hat Nachteile:

  • Ein Array hat eine feste Größe – unpraktisch für dynamische Daten.
  • Keine Sammlungsmethoden (stream(), filter(), remove()).
  • Schwieriger erweiterbar, falls später ein List benötigt wird.


Daher möchten Sie in 90 % der Fälle ein List<MyClass> erhalten. Und hier beginnt das Interessante – Type Erasure in Java. Wenn Sie schreiben:



List<MyClass> list = mapper.readValue(json, List.class); // warning: unchecked


Wird der Compiler warnen, und zur Laufzeit erhalten Sie ein List<LinkedHashMap>, kein List<MyClass>. Generics werden gelöscht, und Jackson weiß nicht, worauf die Elemente gemappt werden sollen.



TypeReference: Der richtige Weg für List



Die Lösung ist die Verwendung von TypeReference. Dies ist eine anonyme innere Klasse, die die Generics-Informationen über Reflektion bewahrt:



List<MyClass> list = mapper.readValue(json, new TypeReference<List<MyClass>>() {});


Beachten Sie das {} – dies erzeugt eine anonyme Klasse, die den Typ erfasst. Jackson versteht über TypeFactory, dass ein List von MyClass deserialisiert werden soll. Dieser Ansatz ist der Goldstandard im Jahr 2025.



Wann ist TypeReference unpraktisch?

  • Wenn Sie den Typ dynamisch erstellen (z. B. aus einer Konfiguration).
  • Wenn Sie dasselbe oft deserialisieren müssen – jedes Mal eine anonyme Klasse zu erstellen, ist teuer.


Für diese Fälle gibt es eine Alternative – CollectionType.



CollectionType: Die Macht von JavaType



Jackson bietet TypeFactory zum Erstellen komplexer Typen:



JavaType type = mapper.getTypeFactory()    .constructCollectionType(List.class, MyClass.class);List<MyClass> list = mapper.readValue(json, type);


Diese Methode:

  • Erzeugt keine anonymen Klassen (weniger Overhead).
  • Ermöglicht das dynamische Erstellen von Typen: constructParametricType(Map.class, String.class, MyClass.class).
  • Ist ideal für Bibliotheken und Frameworks, bei denen die Typen zur Kompilierzeit unbekannt sind.


Best Practice 2025: Verwenden Sie TypeReference für einfache Fälle, CollectionType – wenn Flexibilität oder Leistung erforderlich ist.



Reader und InputStream: Vergessen Sie nicht die Ressourcen



Blogs

Buchempfehlungen