{"id":603,"date":"2025-05-10T23:51:16","date_gmt":"2025-05-10T22:51:16","guid":{"rendered":"https:\/\/www.javaeinfacherkl\u00e4rt.de\/?p=603"},"modified":"2025-06-10T23:56:24","modified_gmt":"2025-06-10T22:56:24","slug":"objenesis-instanziierung-in-java-jenseits-des-konstruktors","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=603","title":{"rendered":"Objenesis: Instanziierung in Java jenseits des Konstruktors"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Einf\u00fchrung<\/h2>\n\n\n\n<p>In der objektorientierten Programmierung ist die Instanziierung von Klassen ein zentraler Bestandteil. In Java geschieht dies \u00fcblicherweise \u00fcber Konstruktoren \u2013 entweder explizit mit dem <code>new<\/code>-Operator oder implizit durch Reflexion mit <code>Constructor.newInstance()<\/code>. Doch was passiert, wenn man ein Objekt <em>ohne<\/em> Aufruf eines Konstruktors erzeugen m\u00f6chte? Genau hier kommt die Bibliothek <strong>Objenesis<\/strong> ins Spiel.<\/p>\n\n\n\n<p>Objenesis ist eine kleine, aber m\u00e4chtige Java-Bibliothek, die es erlaubt, Instanzen von Klassen zu erzeugen, ohne dabei einen Konstruktor aufzurufen. Das ist besonders n\u00fctzlich in Szenarien wie Serialisierung, Framework-Entwicklung oder beim Erstellen von Proxys und Mocks in Unit Tests.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Motivation und Anwendungsf\u00e4lle<\/h2>\n\n\n\n<p>Warum sollte man ein Objekt ohne Konstruktoraufruf instanziieren wollen? Es gibt mehrere Szenarien:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Serialisierung\/Deserialisierung:<\/strong> Beim Wiederherstellen eines Objekts aus einem gespeicherten Zustand (z.\u202fB. JSON oder Bin\u00e4rdaten) m\u00f6chte man eine Instanz erzeugen, deren Zustand anschlie\u00dfend manuell gesetzt wird. Konstruktoren w\u00e4ren hier nicht nur unn\u00f6tig, sondern k\u00f6nnten sogar zu Fehlern f\u00fchren, wenn sie z.\u202fB. Seiteneffekte haben oder bestimmte Argumente erwarten.<\/li>\n\n\n\n<li><strong>Frameworks und Dependency Injection:<\/strong> Frameworks wie Spring, Hibernate oder JPA ben\u00f6tigen Instanzen von Klassen, die nicht unbedingt \u00f6ffentlich zug\u00e4ngliche oder \u00fcberhaupt definierte Konstruktoren haben.<\/li>\n\n\n\n<li><strong>Mocking und Testing:<\/strong> Test-Frameworks wie Mockito oder EasyMock erstellen oft dynamische Proxys. Diese ben\u00f6tigen oft Objekte, die keinen brauchbaren Standardkonstruktor besitzen.<\/li>\n\n\n\n<li><strong>Objekterstellung f\u00fcr unbekannte Klassen:<\/strong> In generischen Bibliotheken, die mit beliebigen Typen umgehen m\u00fcssen, kann der Konstruktoraufruf zu einer Einschr\u00e4nkung werden.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Funktionsweise von Objenesis<\/h2>\n\n\n\n<p>Objenesis umgeht die Konstruktoraufrufe durch den Einsatz von Low-Level-Mechanismen. Intern verwendet es plattformspezifische Techniken, abh\u00e4ngig von der verwendeten Java Virtual Machine (JVM), um Instanzen zu erzeugen.<\/p>\n\n\n\n<p>Ein typisches Beispiel f\u00fcr eine solche Technik ist der Zugriff auf native Methoden oder Unsafe-Klassen (<code>sun.misc.Unsafe<\/code>), mit denen sich Objekte im Speicher allokieren lassen, ohne dass der Konstruktor aufgerufen wird.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Grundlegende Klassen<\/h3>\n\n\n\n<p>Die Hauptkomponenten von Objenesis sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Objenesis<\/code>: Das Interface zur Erstellung von Objekten ohne Konstruktoraufruf.<\/li>\n\n\n\n<li><code>ObjenesisStd<\/code>: Eine Standardimplementierung, die auf m\u00f6glichst viele JVMs abzielt.<\/li>\n\n\n\n<li><code>ObjenesisSerializer<\/code>: Eine Implementierung, die speziell auf serialisierbare Objekte zugeschnitten ist.<\/li>\n\n\n\n<li><code>ObjectInstantiator&lt;T><\/code>: Ein generisches Interface zur Definition eines Fabrik-Objekts, das Instanzen vom Typ <code>T<\/code> erstellen kann.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Beispielcode<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Maven-Abh\u00e4ngigkeit<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.objenesis<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>objenesis<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>3.3<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span> <span class=\"hljs-comment\">&lt;!-- aktuelle Version pr\u00fcfen --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Verwendung<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> org.objenesis.Objenesis;\n<span class=\"hljs-keyword\">import<\/span> org.objenesis.ObjenesisStd;\n<span class=\"hljs-keyword\">import<\/span> org.objenesis.instantiator.ObjectInstantiator;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ObjenesisExample<\/span> <\/span>{\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyClass<\/span> <\/span>{\n        public MyClass() {\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> RuntimeException(<span class=\"hljs-string\">\"Konstruktor sollte nicht aufgerufen werden!\"<\/span>);\n        }\n    }\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) {\n        Objenesis objenesis = <span class=\"hljs-keyword\">new<\/span> ObjenesisStd();\n\n        ObjectInstantiator&lt;MyClass&gt; instantiator =\n            objenesis.getInstantiatorOf(MyClass.class);\n\n        MyClass instance = instantiator.newInstance();\n        System.out.println(<span class=\"hljs-string\">\"Instanz erzeugt: \"<\/span> + instance);\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Ausgabe:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Instanz erzeugt: ObjenesisExample$MyClass@<span class=\"hljs-number\">7<\/span>c30a502\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Wie zu sehen ist, wurde der Konstruktor <strong>nicht<\/strong> aufgerufen \u2013 andernfalls h\u00e4tte das Programm mit einer <code>RuntimeException<\/code> abgebrochen.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Sicherheitsaspekte und Einschr\u00e4nkungen<\/h2>\n\n\n\n<p>Objenesis ist ein m\u00e4chtiges Werkzeug, bringt jedoch auch einige Risiken und Einschr\u00e4nkungen mit sich:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Sicherheitsrichtlinien:<\/strong> In restriktiven Umgebungen (z.\u202fB. Sandboxes oder mit aktivem SecurityManager) kann der Zugriff auf native oder Unsafe-Operationen unterbunden sein.<\/li>\n\n\n\n<li><strong>JVM-Kompatibilit\u00e4t:<\/strong> Obwohl Objenesis verschiedene JVMs unterst\u00fctzt (HotSpot, OpenJ9, Android ART usw.), kann es bei bestimmten Versionen oder Einstellungen zu Inkompatibilit\u00e4ten kommen. Seit Java 9 ist der Zugriff auf intern verwendete APIs wie <code>sun.misc.Unsafe<\/code> durch das Module-System erschwert.<\/li>\n\n\n\n<li><strong>Objektzustand:<\/strong> Da Konstruktoren nicht ausgef\u00fchrt werden, ist der interne Zustand der Objekte m\u00f6glicherweise nicht konsistent. Es liegt in der Verantwortung des Entwicklers, die Felder korrekt zu initialisieren.<\/li>\n\n\n\n<li><strong>Nicht f\u00fcr Produktivcode empfohlen:<\/strong> In vielen F\u00e4llen ist der Einsatz von Objenesis nur in spezifischen Frameworks oder Testumgebungen gerechtfertigt. F\u00fcr normale Anwendungsentwicklung ist der klassische Weg der Objekterzeugung vorzuziehen.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Alternativen und Integration<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Alternativen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Reflection API:<\/strong> <code>Constructor.newInstance()<\/code> ruft jedoch immer den Konstruktor auf.<\/li>\n\n\n\n<li><strong>sun.misc.Unsafe:<\/strong> Direkter Zugriff auf Low-Level-Operationen, jedoch unsicher und nicht portabel.<\/li>\n\n\n\n<li><strong>JVM-spezifische L\u00f6sungen:<\/strong> Manche Frameworks verwenden bytecode-manipulierende Tools wie ASM oder Javassist.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Integration in andere Frameworks<\/h3>\n\n\n\n<p>Viele bekannte Bibliotheken und Frameworks setzen intern auf Objenesis, ohne dass der Entwickler direkt damit in Kontakt kommt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Spring Framework:<\/strong> F\u00fcr die Instanziierung von Beans, insbesondere bei Proxies.<\/li>\n\n\n\n<li><strong>Mockito:<\/strong> F\u00fcr die Erstellung von Mock-Objekten ohne Konstruktor.<\/li>\n\n\n\n<li><strong>Hibernate:<\/strong> Beim Laden von Entit\u00e4ten aus einer Datenbank.<\/li>\n\n\n\n<li><strong>Kryo:<\/strong> F\u00fcr effiziente Serialisierung und Deserialisierung.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p>Objenesis ist ein n\u00fctzliches Werkzeug im Java-\u00d6kosystem, das in bestimmten Anwendungsf\u00e4llen unverzichtbar ist. Es erm\u00f6glicht die Instanziierung von Objekten auf niedrigster Ebene, ohne den Konstruktor aufzurufen, was insbesondere bei Serialisierung, Dependency Injection und dynamischer Proxy-Erstellung enorme Vorteile bietet.<\/p>\n\n\n\n<p>Allerdings sollte der Einsatz wohl\u00fcberlegt sein: Die Umgehung der Konstruktorlogik kann zu schwer nachvollziehbaren Fehlern f\u00fchren und den Code schwerer wartbar machen. In den H\u00e4nden von Framework-Entwicklern oder in kontrollierten Testumgebungen ist Objenesis jedoch eine wertvolle Ressource.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Einf\u00fchrung In der objektorientierten Programmierung ist die Instanziierung von Klassen ein zentraler Bestandteil. In Java geschieht dies \u00fcblicherweise \u00fcber Konstruktoren \u2013 entweder explizit mit dem new-Operator oder implizit durch Reflexion mit Constructor.newInstance(). Doch was passiert, wenn man ein Objekt ohne Aufruf eines Konstruktors erzeugen m\u00f6chte? Genau hier kommt die Bibliothek Objenesis ins Spiel. Objenesis ist [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-603","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/603","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=603"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/603\/revisions"}],"predecessor-version":[{"id":604,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/603\/revisions\/604"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=603"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=603"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=603"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}