{"id":48852,"date":"2025-05-08T14:49:50","date_gmt":"2025-05-08T12:49:50","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=48852"},"modified":"2026-06-10T10:59:27","modified_gmt":"2026-06-10T08:59:27","slug":"initialization-on-demand-holder-idiom","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/initialization-on-demand-holder-idiom\/","title":{"rendered":"Initialization-on-Demand Holder Idiom in Java"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Das <em>Initialization-on-Demand Holder Idiom<\/em> ist ein sicherer und effizienter Weg, um in Multithreading-Anwendungen statische Felder erst bei Bedarf zu initialisieren. Es verhindert dabei subtile Race Conditions, ohne die Performance durch vollst\u00e4ndige Synchronisierung aller Zugriffe zu beeintr\u00e4chtigen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In diesem Artikel erf\u00e4hrst du:<\/p>\n\n\n\n<ul class=\"wp-block-list hc-checked-list\">\n<li>Was ist die Motivation f\u00fcr das <em>Initialization-on-Demand Holder<\/em> Idiom?<\/li>\n\n\n\n<li>Warum ist die vollst\u00e4ndige Synchronisierung mit <code>synchronized<\/code> nicht optimal?<\/li>\n\n\n\n<li>Wie wird das <em>Initialization-on-Demand Holder<\/em> Idiom in Java implementiert?<\/li>\n\n\n\n<li>Welche Alternativen gibt es?<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"motivation\">Motivation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bei zeitaufw\u00e4ndigen Initialisierungsprozessen ist es oft ratsam, diese erst bei tats\u00e4chlichem Bedarf durchzuf\u00fchren. Beispielsweise k\u00f6nnte es Sinn machen, einen Logger, der eine Verbindung zu einer Datenbank aufbaut, erst dann zu initialisieren, wenn das erste Mal etwas geloggt wird. Diese \u201eLazy Initialization\u201c verhindert unn\u00f6tige Verz\u00f6gerungen beim Programmstart.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In einer Single-Thread-Umgebung ist die Implementierung unkompliziert:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserService<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Logger logger;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Logger <span class=\"hljs-title\">getLogger<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">if<\/span> (logger == <span class=\"hljs-keyword\">null<\/span>) {\n            logger = initializeLogger();\n        }\n        <span class=\"hljs-keyword\">return<\/span> logger;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">createUser<\/span><span class=\"hljs-params\">(User user)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ . . .<\/span>\n        getLogger().info(<span class=\"hljs-string\">\"User created\"<\/span>);\n    }\n\n    <span class=\"hljs-comment\">\/\/ . . .<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Der erste Aufruf von <code>getLogger()<\/code> initialisiert den Logger und speichert ihn im statischen Feld <code>logger<\/code>. Nachfolgende Aufrufe liefern direkt das gespeicherte Objekt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Implementierung ist allerdings nicht threadsicher.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In einer Multithreading-Anwendung k\u00f6nnen hier verschiedene subtile Effekte auftreten, die zu kaum zu reproduzierenden und damit nur schwer zu behebenden Race Conditions f\u00fchren k\u00f6nnen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bei nahezu gleichzeitigem ersten Aufruf der <code>getLogger()<\/code>-Methode aus zwei Threads k\u00f6nnten beide Threads das <code>logger<\/code>-Feld als <code>null<\/code> sehen, so dass der Logger mehrfach initialisiert wird.<\/li>\n\n\n\n<li>Durch Thread-Caching-Effekte k\u00f6nnte ein Thread selbst dann, wenn ein anderer Thread das <code>logger<\/code>-Feld bereits zugewiesen hat, dieses noch als <code>null<\/code> sehen.<\/li>\n\n\n\n<li>Durch Instruction Reordering k\u00f6nnte ein Thread das <code>logger<\/code>-Feld als nicht <code>null<\/code> sehen, dieses k\u00f6nnte aber auf ein noch nicht vollst\u00e4ndig initialisiertes <code>Logger<\/code>-Objekt zeigen.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Die drei Effekte habe ich im Artikel \u00fcber das <a href=\"https:\/\/www.happycoders.eu\/de\/java\/double-checked-locking\/#effekt-1-mehrfache-initialisierung-durch-verzahnung-der-thread-ausfuehrungen\">Double-Checked Locking Idiom<\/a> ausf\u00fchrlich beschrieben.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Multithreading-Anwendungen m\u00fcssen wir daher den Zugriff auf das <code>logger<\/code>-Feld durch geeignete Ma\u00dfnahmen synchronisieren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"loesung-1-vollstaendige-synchronisation\">L\u00f6sung 1: Vollst\u00e4ndige Synchronisation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Der einfachste Ansatz ist eine vollst\u00e4ndige Synchronisation der <code>getLogger()<\/code>-Methode durch <code>synchronized<\/code> (oder alternativ ein explizites Lock):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/           \u2193     <\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">synchronized<\/span> <span class=\"hljs-keyword\">static<\/span> Logger <span class=\"hljs-title\">getLogger<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (logger == <span class=\"hljs-keyword\">null<\/span>) {\n        logger = initializeLogger();\n    }\n    <span class=\"hljs-keyword\">return<\/span> logger;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Diese Implementierung f\u00fchrt jedoch zu erheblichen Performance-Einbu\u00dfen, da:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>jeder Aufruf den Verwaltungsoverhead einer kompletten Synchronisation erfordert,<\/li>\n\n\n\n<li>Threads bei parallelen Zugriffen warten m\u00fcssen,<\/li>\n\n\n\n<li>Ein- und Austritt aus dem <code>synchronized<\/code>-Block Speicherbarrieren erzwingen, die die Sichtbarkeit zwischen Threads sicherstellen.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Aufgrund dieses signifikanten Mehraufwands ist diese L\u00f6sung insbesondere f\u00fcr oft aufgerufene Methoden nicht optimal.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"loesung-2-double-checked-locking\">L\u00f6sung 2: Double-Checked Locking<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Eine weitere L\u00f6sungsm\u00f6glichkeit ist das oben bereits erw\u00e4hnte <a href=\"https:\/\/www.happycoders.eu\/de\/java\/double-checked-locking\/\">Double-Checked Locking<\/a>. Dieses habe ich ausf\u00fchrlich in dem verlinkten Artikel erl\u00e4utert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein korrekt implementiertes Double-Checked Locking l\u00f6st die oben genannten Performance-Probleme, ist aber recht kompliziert und damit fehleranf\u00e4llig in der Implementierung.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"loesung-3-initialization-on-demand-holder\">L\u00f6sung 3: Initialization-on-Demand Holder<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Die dritte L\u00f6sung ist das <em>Initialization-on-Demand Holder<\/em> Idiom. Auch dieses l\u00f6st die oben genannten Performance-Probleme. Es ist einfacher umzusetzen als Double-Checked Locking und damit weniger fehleranf\u00e4llig \u2013 es funktioniert aber nur mit <em>statischen<\/em> Feldern, nicht mit Instanzfeldern.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Und so wird es implementiert:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserService<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">LoggerHolder<\/span> <\/span>{\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Logger LOGGER = initializeLogger();\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">createUser<\/span><span class=\"hljs-params\">(User user)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ . . .<\/span>\n        LoggerHolder.LOGGER.info(<span class=\"hljs-string\">\"User created\"<\/span>);\n    }\n\n    <span class=\"hljs-comment\">\/\/ . . .<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Hier wird das <code>Logger<\/code>-Objekt im statischen <code>LOGGER<\/code>-Feld der inneren Klasse <code>LoggerHolder<\/code> gespeichert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber wird damit der Logger nicht schon beim Programmstart initialisiert? Wollten wir nicht genau das vermeiden?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nein, denn die JVM l\u00e4dt und initialisiert eine Klasse erst dann, wenn sie ben\u00f6tigt wird.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-stellt-das-initialization-on-demand-holder-idiom-die-lazy-initialization-sicher\">Wie stellt das Initialization-on-Demand Holder Idiom die Lazy Initialization sicher?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn die JVM (die Java Virtual Machine) die <code>UserService<\/code>-Klasse l\u00e4dt, l\u00e4dt sie <em>nicht<\/em> automatisch die <code>LoggerHolder<\/code>-Klasse mit. Sie l\u00e4dt die Klasse erst dann, wenn zur Laufzeit zum ersten Mal auf <code>LoggerHolder.LOGGER<\/code> zugegriffen wird.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hier ist ein kleines Demo-Programm, mit dem du das ausprobieren kannst:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">InitializationOnDemandHolderIdiomDemo<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">LoggerHolder<\/span> <\/span>{\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Logger LOGGER = initializeLogger();\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Logger <span class=\"hljs-title\">initializeLogger<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n            System.out.println(<span class=\"hljs-string\">\"&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\"<\/span>);\n            <span class=\"hljs-keyword\">return<\/span> Logger.getLogger(\n                    InitializationOnDemandHolderIdiomDemo<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getName<\/span>())<\/span>;\n        }\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n        InitializationOnDemandHolderIdiomDemo demo =\n                <span class=\"hljs-keyword\">new<\/span> InitializationOnDemandHolderIdiomDemo();\n\n        demo.doSomethingWithoutLogging();\n        demo.doSomethingWithoutLogging();\n        demo.doSomethingWithoutLogging();\n\n        demo.doSomethingWithLogging();\n        demo.doSomethingWithLogging();\n        demo.doSomethingWithLogging();\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">doSomethingWithoutLogging<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        System.out.println(<span class=\"hljs-string\">\"Not logging\"<\/span>);\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">doSomethingWithLogging<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        System.out.println(<span class=\"hljs-string\">\"\\nI'm going to log something...\"<\/span>);\n        LoggerHolder.LOGGER.info(<span class=\"hljs-string\">\"Some log message\"<\/span>);\n        System.out.println(<span class=\"hljs-string\">\"Logged something\"<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Du wirst folgende Ausgabe sehen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Not logging\nNot logging\nNot logging\n\nI'm going to log something...\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\nJun 10, 2026 9:33:16 AM eu.happycoders.iodh.InitializationOnDemandHolderIdiomDemo doSomethingWithLogging\nINFO: Some log message\nLogged something\n\nI'm going to log something...\nJun 10, 2026 9:33:16 AM eu.happycoders.iodh.InitializationOnDemandHolderIdiomDemo doSomethingWithLogging\nINFO: Some log message\nLogged something\n\nI'm going to log something...\nJun 10, 2026 9:33:16 AM eu.happycoders.iodh.InitializationOnDemandHolderIdiomDemo doSomethingWithLogging\nINFO: Some log message\nLogged something<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">(Die Logger-Ausgaben \u2013 Zeitstempel- und <code>INFO:<\/code>-Zeile \u2013 gehen auf <code>System.err<\/code>, die \u00fcbrigen Zeilen auf <code>System.out<\/code> \u2013 die genaue Reihenfolge beider Str\u00f6me kann je nach Umgebung leicht abweichen.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Du siehst: Der Logger wird erst dann \u2013 und nur dann \u2013 initialisiert, wenn er das erste Mal ben\u00f6tigt wird. Damit k\u00f6nnen wir an die Anforderung \u201eLazy Initialization\u201c einen Haken setzen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Und was ist mit der Threadsicherheit? <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-garantiert-das-initialization-on-demand-holder-idiom-die-threadsicherheit\">Wie garantiert das Initialization-on-Demand Holder Idiom die Threadsicherheit?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Die Threadsicherheit wird beim Laden und Initialisieren von Klassen automatisch durch die JVM (die Java Virtual Machine) garantiert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">D. h. wenn der erste Zugriff auf <code>LoggerHolder.LOGGER<\/code> gleichzeitig durch zwei Threads erfolgen sollte, dann stellt die JVM zum einen sicher, dass das <code>LoggerHolder.LOGGER<\/code> nur einmal initialisiert wird \u2013 und zum anderen, dass beide Threads das vollst\u00e4ndig initialisierte <code>Logger<\/code>-Objekt sehen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das klingt ja fast zu sch\u00f6n um wahr zu sein...<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"nachteil-des-initialization-on-demand-holder-idioms\">Nachteil des Initialization-on-Demand Holder Idioms<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wie fast immer gibt es auch bei dieser L\u00f6sung einen Nachteil:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn beim ersten Zugriff auf <code>LoggerHolder.LOGGER<\/code> der Aufruf der <code>initializeLogger()<\/code>-Methode fehlschlagen sollte, dann wird bei folgenden Zugriffen nicht etwa erneut versucht, <code>initializeLogger()<\/code> aufzurufen. Nein \u2013 wenn das Initialisieren einer Klasse einmal fehlgeschlagen ist, wird die JVM nicht erneut versuchen, die Klasse zu initialisieren. Stattdessen wird jeder weitere Zugriff auf <code>LoggerHolder.LOGGER<\/code> unverz\u00fcglich zu einem <code>NoClassDefFoundError<\/code> f\u00fchren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hier ist ein kleines Programm, das das Verhalten demonstriert:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">InitializationOnDemandHolderIdiomErrorDemo<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">LoggerHolder<\/span> <\/span>{\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Logger LOGGER = initializeLogger();\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Logger <span class=\"hljs-title\">initializeLogger<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n            System.out.println(<span class=\"hljs-string\">\"&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\"<\/span>);\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> RuntimeException(<span class=\"hljs-string\">\"Initialization failed\"<\/span>);\n        }\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n        InitializationOnDemandHolderIdiomErrorDemo demo =\n                <span class=\"hljs-keyword\">new<\/span> InitializationOnDemandHolderIdiomErrorDemo();\n\n        demo.doSomethingWithLogging();\n        demo.doSomethingWithLogging();\n        demo.doSomethingWithLogging();\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">doSomethingWithLogging<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">try<\/span> {\n            System.out.println(<span class=\"hljs-string\">\"\\nI'm going to log something...\"<\/span>);\n            LoggerHolder.LOGGER.info(<span class=\"hljs-string\">\"I did something smart\"<\/span>);\n            System.out.println(<span class=\"hljs-string\">\"Logged something\"<\/span>);\n        } <span class=\"hljs-keyword\">catch<\/span> (Throwable t) {\n            System.out.println(<span class=\"hljs-string\">\"&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; \"<\/span> + t.getClass().getName() + <span class=\"hljs-string\">\" &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\"<\/span>);\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Das Programm gibt folgendes aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">I'm going to log something...\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; java.lang.ExceptionInInitializerError &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n\nI'm going to log something...\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; java.lang.NoClassDefFoundError &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n\nI'm going to log something...\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; java.lang.NoClassDefFoundError &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Du siehst: Nur beim ersten Zugriff auf <code>LoggerHolder.LOGGER<\/code> wird <code>initializeLogger()<\/code> aufgerufen. Alle folgenden Zugriffe f\u00fchren direkt zu einem <code>NoClassDefFoundError<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bei den anderen L\u00f6sungen \u2013 vollst\u00e4ndiger Synchronisation und Double-Checked Locking \u2013 w\u00fcrde hingegen bei jedem weiteren Aufruf der <code>getLogger()<\/code>-Methode erneut versucht werden, das <code>Logger<\/code>-Objekt zu initialisieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hier ein entsprechendes Demo f\u00fcr die Variante mit vollst\u00e4ndiger Synchronisation:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">LazyInitializationErrorDemo<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Logger logger;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">synchronized<\/span> <span class=\"hljs-keyword\">static<\/span> Logger <span class=\"hljs-title\">getLogger<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">if<\/span> (logger == <span class=\"hljs-keyword\">null<\/span>) {\n            logger = initializeLogger();\n        }\n        <span class=\"hljs-keyword\">return<\/span> logger;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Logger <span class=\"hljs-title\">initializeLogger<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        System.out.println(<span class=\"hljs-string\">\"&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\"<\/span>);\n        <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> RuntimeException(<span class=\"hljs-string\">\"Initialization failed\"<\/span>);\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n        LazyInitializationErrorDemo demo = <span class=\"hljs-keyword\">new<\/span> LazyInitializationErrorDemo();\n\n        demo.doSomethingWithLogging();\n        demo.doSomethingWithLogging();\n        demo.doSomethingWithLogging();\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">doSomethingWithLogging<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">try<\/span> {\n            System.out.println(<span class=\"hljs-string\">\"\\nI'm going to log something...\"<\/span>);\n            getLogger().info(<span class=\"hljs-string\">\"I did something smart\"<\/span>);\n            System.out.println(<span class=\"hljs-string\">\"Logged something\"<\/span>);\n        } <span class=\"hljs-keyword\">catch<\/span> (Throwable t) {\n            System.out.println(<span class=\"hljs-string\">\"&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; \"<\/span> + t.getClass().getName() + <span class=\"hljs-string\">\" &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\"<\/span>);\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Und hier die Ausgabe des Programms:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">I'm going to log something...\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; java.lang.RuntimeException &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n\nI'm going to log something...\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; java.lang.RuntimeException &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n\nI'm going to log something...\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Initializing logger &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; java.lang.RuntimeException &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Hier wird nun bei jedem Aufruf von <code>getLogger()<\/code> erneut versucht, den Logger zu initialisieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ob das gew\u00fcnscht ist oder nicht, h\u00e4ngt selbstverst\u00e4ndlich von den Anforderungen ab.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"die-drei-loesungen-im-vergleich\">Die drei L\u00f6sungen im Vergleich<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor wir den Blick nach vorn richten, hier die drei L\u00f6sungen noch einmal nebeneinander:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Kriterium<\/th><th>Vollst\u00e4ndige Synchronisation<\/th><th>Double-Checked Locking<\/th><th>Initialization-on-Demand Holder<\/th><\/tr><\/thead><tbody><tr><td><strong>Performance<\/strong><\/td><td>gering \u2013 jeder Zugriff wird synchronisiert<\/td><td>hoch \u2013 synchronisiert nur bei der Initialisierung<\/td><td>hoch \u2013 keine Synchronisation nach dem Klassenladen<\/td><\/tr><tr><td><strong>Implementierungs\u00adkomplexit\u00e4t<\/strong><\/td><td>niedrig<\/td><td>hoch und fehleranf\u00e4llig (u. a. <code>volatile<\/code> n\u00f6tig)<\/td><td>niedrig und schwer falsch zu machen<\/td><\/tr><tr><td><strong>Anwendbar auf<\/strong><\/td><td>statische Felder und Instanzfelder<\/td><td>statische Felder und Instanzfelder<\/td><td>nur statische Felder<\/td><\/tr><tr><td><strong>Verhalten bei fehlgeschlagener Initialisierung<\/strong><\/td><td>erneuter Versuch bei jedem Aufruf<\/td><td>erneuter Versuch bei jedem Aufruf (Feld bleibt <code>null<\/code>)<\/td><td>kein erneuter Versuch \u2013 danach <code>NoClassDefFoundError<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn du also ein statisches Feld threadsicher und performant lazy initialisieren willst, ist das Initialization-on-Demand Holder Idiom in der Regel die einfachste Wahl. F\u00fcr Instanzfelder bleibt \u2013 mit dem genannten Mehraufwand \u2013 nur Double-Checked Locking.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"kommende-alternative-lazy-constants\">Kommende Alternative: Lazy Constants<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Auch den JDK-Entwickler:innen ist bewusst, dass die existierenden L\u00f6sungen allesamt nicht optimal sind. Daher wird aktuell an einem neuen Feature gearbeitet: <a href=\"https:\/\/www.happycoders.eu\/de\/java\/lazy-constants\/\">Lazy Constants<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Lazy Constants<\/em> wurden in <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-25-features\/#stable-values-preview-jep-502\">Java 25<\/a> unter dem Namen <em>Stable Values<\/em> als Preview-Version eingef\u00fchrt und in <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-26-features\/#lazy-constants-second-preview-jep-526\">Java 26<\/a> in <em>Lazy Constants<\/em> umbenannt und grundlegend \u00fcberarbeitet. Eine <em>Lazy Constant<\/em> ist ein Container, der die threadsichere Initialisierung von Konstanten beim ersten Zugriff darauf hinter einer einfachen API kapselt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So sieht das an unserem Logger-Beispiel aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserService<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> LazyConstant&lt;Logger&gt; LOGGER =\n            LazyConstant.of(UserService::initializeLogger);\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">createUser<\/span><span class=\"hljs-params\">(User user)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ . . .<\/span>\n        LOGGER.get().info(<span class=\"hljs-string\">\"User created\"<\/span>);\n    }\n\n    <span class=\"hljs-comment\">\/\/ . . .<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Mit der Factory-Methode <code>LazyConstant.of(...)<\/code> \u00fcbergeben wir nur die Funktion, die den Wert berechnet \u2013 initialisiert wird die Konstante damit noch nicht. Erst der erste Aufruf von <code>LOGGER.get()<\/code> ruft <code>initializeLogger()<\/code> auf und speichert das Ergebnis; jeder weitere <code>get()<\/code>-Aufruf liefert direkt das gespeicherte Logger-Objekt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Auch hier ist die Initialisierung threadsicher: Selbst bei gleichzeitigem Zugriff aus mehreren Threads wird der Wert nur einmal berechnet. Anders als beim Holder Idiom sorgt daf\u00fcr aber nicht der Klassenlade-Mechanismus der JVM, sondern die <code>LazyConstant<\/code>-Implementierung selbst.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Und da <code>LOGGER<\/code> in einem <code>static final<\/code>-Feld liegt, kann die JVM ihn nach der Initialisierung als echte Konstante behandeln und entsprechend optimieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Unterschied zum Holder Idiom: Schl\u00e4gt die Initialisierung fehl, bleibt die Lazy Constant uninitialisiert \u2013 beim n\u00e4chsten <code>get()<\/code>-Aufruf wird die Berechnung erneut versucht. Du erh\u00e4ltst also nicht \u2013 wie beim Holder Idiom \u2013 bei jedem weiteren Zugriff einen <code>NoClassDefFoundError<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Da Lazy Constants in Java 26 noch ein Preview-Feature sind, musst du sie beim Kompilieren und Ausf\u00fchren mit <code>--enable-preview<\/code> aktivieren. In <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-27-features\/#lazy-constants-third-preview-jep-531\">Java 27<\/a> \u2013 zum Zeitpunkt dieses Artikels in Rampdown Phase 1 \u2013 folgt mit <a href=\"https:\/\/openjdk.org\/jeps\/531\" target=\"_blank\" rel=\"noreferrer noopener\">JEP 531<\/a> eine dritte Preview-Runde.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fazit\">Fazit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Um Felder in Multithreading-Anwendungen erst bei Bedarf zu initialisieren, k\u00f6nnen wir das <a href=\"https:\/\/www.happycoders.eu\/de\/java\/double-checked-locking\/\">Double-Checked Locking Idiom<\/a> oder \u2013 f\u00fcr statische Felder \u2013 das in diesem Artikel beschriebene <em>Initialization-on-Demand Holder<\/em> Idiom einsetzen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beide Varianten sind performanter als eine vollst\u00e4ndige Synchronisation der Zugriffsmethode mit <code>synchronized<\/code> oder einem expliziten Lock.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beide Varianten sind allerdings auch kompliziert in der Implementierung \u2013 und das kann leicht zu Fehlern f\u00fchren \u2013 vor allem, da sich eine fehlerhafte Implementierung nur durch Race Conditions offenbart, und damit in der Regel nicht sofort, sondern unter Umst\u00e4nden erst nach Wochen oder Monaten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An einer performanten und gleichzeitig leicht zu implementierenden Variante wird derzeit gearbeitet: <a href=\"https:\/\/www.happycoders.eu\/de\/java\/lazy-constants\/\">Lazy Constants<\/a> (zum Stand von Java 26 und 27 im Preview-Stadium).<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>Du m\u00f6chtest \u00fcber alle neuen Java-Features auf dem Laufenden sein? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>Erfahre, wie das Initialization-on-Demand Holder Idiom in Java sichere und effiziente Lazy-Initialisierung ohne Performance-Einbu\u00dfen erm\u00f6glicht.<\/p>\n","protected":false},"author":1,"featured_media":48968,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"Erfahre, wie das Initialization-on-Demand Holder Idiom in Java eine threadsichere Lazy Initialization ohne Synchronisations-Overhead erm\u00f6glicht.","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"initialization-on-demand holder","_seopress_news_disabled":"","_seopress_video_disabled":"","_seopress_video":[],"_seopress_pro_schemas_manual":[],"_seopress_pro_rich_snippets_disable_all":"","_seopress_pro_rich_snippets_disable":[],"_seopress_pro_schemas":[],"_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":16222,"_post_count":0,"footnotes":""},"categories":[64],"tags":[165],"class_list":["post-48852","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-fortgeschritten"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/05\/initialization-on-demand-holder-java-feature-image.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"Erfahre, wie das Initialization-on-Demand Holder Idiom in Java sichere und effiziente Lazy-Initialisierung ohne Performance-Einbu\u00dfen erm\u00f6glicht.","public_identification_id":"11e509e11026457ea41def8c18066774","private_identification_id":"3a1c1bd542864785889346932b18aadd","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/48852","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=48852"}],"version-history":[{"count":14,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/48852\/revisions"}],"predecessor-version":[{"id":56658,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/48852\/revisions\/56658"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/48968"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=48852"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=48852"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=48852"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}