{"id":42781,"date":"2025-04-09T09:19:33","date_gmt":"2025-04-09T07:19:33","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=42781"},"modified":"2026-06-04T11:45:40","modified_gmt":"2026-06-04T09:45:40","slug":"lazy-constants","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/lazy-constants\/","title":{"rendered":"Lazy Constants in Java (ehem. Stable Values) \u2013 Werte sicher lazy initialisieren"},"content":{"rendered":"\n<p><em>Lazy Constants<\/em> (in Java 25 hie\u00dfen sie noch noch <em>Stable Values<\/em>) sind Werte, die zur Laufzeit einer Anwendung nur ein einziges Mal zugewiesen werden k\u00f6nnen \u2013 dies aber zu einem beliebigen Zeitpunkt \u2013 und danach konstant bleiben. Sie standardisieren die verz\u00f6gerte Initialisierung (\u201elazy initialization\u201c) von Konstanten und erlauben der JVM, diese Konstanten so zu optimieren, wie sie es auch f\u00fcr finale (\u201efinal\u201c) Werte tun kann.<\/p>\n\n\n\n<p>In diesem Artikel erf\u00e4hrst du:<\/p>\n\n\n\n<ul class=\"wp-block-list hc-checked-list\">\n<li>Was sind <em>Lazy Constants<\/em> und wie benutzt man sie?<\/li>\n\n\n\n<li>Welche Vorteile bringt die Unver\u00e4nderlichkeit einer <em>Lazy Constant<\/em>?<\/li>\n\n\n\n<li>Wie haben wir Unver\u00e4nderlichkeit bisher implementiert, und welche Nachteile hatte das?<\/li>\n\n\n\n<li>Was sind <em>Lazy Lists<\/em> und <em>Lazy Maps<\/em>?<\/li>\n\n\n\n<li>Wie funktionieren <em>Lazy Constants<\/em> intern?<\/li>\n<\/ul>\n\n\n\n<p><em>Lazy Constants<\/em> sind ein Preview-Feature, das in <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-25-features\/\">Java 25<\/a> unter dem Namen <em>Stable Values<\/em> ver\u00f6ffentlicht wurde (<a href=\"https:\/\/openjdk.org\/jeps\/502\" target=\"_blank\" rel=\"noopener\">JDK Enhancement Proposal 502<\/a>) und in Java 26 deutlich vereinfacht und in <em>Lazy Constants<\/em> umbenannt wurde (<a href=\"https:\/\/openjdk.org\/jeps\/502\" target=\"_blank\" rel=\"noopener\">JEP 526<\/a>).<\/p>\n\n\n\n<p>Im den ersten Abschnitten erkl\u00e4re ich, warum wir <em>Lazy Constants<\/em> \u00fcberhaupt brauchen. Falls du dir das schon denken kannst, dann springe gerne direkt zum Abschnitt <a href=\"#die-loesung-lazy-constants\">\u201eDie L\u00f6sung: Lazy Constants\u201c<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"warum-immutability-unveraenderlichkeit\">Warum Immutability (Unver\u00e4nderlichkeit)?<\/h2>\n\n\n\n<p>Im der Einf\u00fchrung habe ich erkl\u00e4rt, dass es sich bei Lazy Constants um Werte handelt, die nur einmal zugewiesen werden, danach aber unver\u00e4nderlich bleiben. Aber was bringt es uns, wenn Werte unver\u00e4nderlich (\u201eimmutable\u201c) sind? Die Unver\u00e4nderlichkeit bringt einige Vorteile mit sich:<\/p>\n\n\n\n<p><strong>1. Ein unver\u00e4nderliches Objekt kann problemlos von mehreren Threads genutzt werden.<\/strong><\/p>\n\n\n\n<p>Es besteht keine Gefahr von Race Conditions, die wir bei ver\u00e4nderlichen Objekten nur durch Synchronisierung oder Memory Barriers verhindern k\u00f6nnen. Dabei schleichen sich selbst bei erfahrenen EntwicklerInnen leicht Fehler ein.<\/p>\n\n\n\n<p><strong>2. Die JVM kann unver\u00e4nderliche Objekte optimieren, z. B. durch Constant Folding.<\/strong><\/p>\n\n\n\n<p>Wenn die JVM z. B. erkennt, dass an mehreren Stellen auf <code>serviceRegistry.userService()<\/code> zugegriffen wird, und sie wei\u00df, dass <code>serviceRegistry<\/code> konstant ist und <code>userService()<\/code> eine Konstante zur\u00fcckgibt, dann kann sie alle Aufrufe von <code>serviceRegistry.userService()<\/code> durch die <code>userService<\/code>-Konstante ersetzen.<\/p>\n\n\n\n<p><strong>3. Unver\u00e4nderliche Objekte machen den Code besser lesbar<\/strong>.<\/p>\n\n\n\n<p>Code ist vorhersehbarer, leichter verst\u00e4ndlich und leichter zu debuggen, wenn man sich keine Gedanken \u00fcber m\u00f6gliche \u00c4nderungen von Objektzust\u00e4nden machen muss. Bei ver\u00e4nderlichen Objekten sollten wir f\u00fcr Parameter und R\u00fcckgabewerte defensive Kopien erstellen, um sicherzustellen, dass diese nicht versehentlich modifiziert werden. Bei unver\u00e4nderlichen Objekten ist das nicht notwendig.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"immutability-mit-final\">Immutability mit \u201efinal\u201c<\/h2>\n\n\n\n<p>Bisher war die einzige M\u00f6glichkeit, um Immutability zu erreichen, Felder eines Objekts mit <code>final<\/code> zu kennzeichnen. Statische finale Felder m\u00fcssen bei der Deklaration oder in einem <code>static<\/code>-Block zugewiesen werden und werden beim Laden der Klasse initialisiert. Finale Instanzfelder m\u00fcssen bei der Deklaration oder im Konstruktor zugewiesen werden und werden beim Erzeugen eines neuen Objekts der Klasse initialisiert.<\/p>\n\n\n\n<p>Im folgenden Beispiel wird ein statisches <code>Logger<\/code>-Feld initialisiert:<\/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> <span class=\"hljs-keyword\">final<\/span> Logger LOGGER = LoggerFactory.getLogger(UserService<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>)<\/span>;\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>Alternativ mit einem <code>static<\/code>-Block:<\/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-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> Logger LOGGER;\n\n  <span class=\"hljs-keyword\">static<\/span> {\n    LOGGER = LoggerFactory.getLogger(UserService<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>)<\/span>;\n  }\n\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\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>Im folgenden Beispiel wird f\u00fcr jedes neue <code>Task<\/code>-Objekt eine unver\u00e4nderliche UUID generiert:<\/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\">Task<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UUID taskId = UUID.randomUUID();\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>Alternativ im Konstruktor:<\/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\">Task<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UUID taskId;\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Task<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    taskId = UUID.randomUUID();\n  }\n\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\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>Nicht immer ist die Initialisierung von Konstanten ganz so einfach. Im Folgenden zeige ich dir einige weniger triviale Beispiele.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"verzoegerte-initialisierung-lazy-initialization\">Verz\u00f6gerte Initialisierung (\u201eLazy Initialization\u201c)<\/h2>\n\n\n\n<p>Finale Felder werden in jedem Fall initialisiert, selbst wenn sie gar nicht (oder erst sehr viel sp\u00e4ter) benutzt werden. Wenn aber die Initialisierung, also z. B. das Erzeugen des Loggers, eine Weile dauert (weil dieser z. B. eine Verbindung zu einem externen Logging-System aufbaut), der Logger dann aber nie (oder erst sp\u00e4ter) im Programmablauf verwendet wird, wurde der Start der Anwendung durch die fr\u00fchzeitige Initialisierung u. U. unn\u00f6tig verlangsamt.<\/p>\n\n\n\n<p>Felder, die teuer zu initialisieren sind, k\u00f6nnen wir verz\u00f6gert, also erst bei Bedarf (\u201elazy\u201c) initialisieren. In einer single-threaded Anwendung ist das einfach:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" 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-comment\">\/\/ Not thread-safe!!!<\/span>\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 = LoggerFactory.getLogger(UserService<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>)<\/span>;\n    }\n    <span class=\"hljs-keyword\">return<\/span> logger;\n  }\n\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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>Ein zweiter Use Case:<\/p>\n\n\n\n<p>Nicht immer haben wir beim Erzeugen eines Objekts alle Informationen vorliegen, die wir f\u00fcr die Initialisierung eines unver\u00e4nderlichen Feldes ben\u00f6tigen. Beispielsweise k\u00f6nnte ein Service erzeugt werden, bevor eine Verbindung zur Datenbank besteht \u2013 der Service muss aber zur Initialisierung eines Feldes auf die Datenbank zugreifen.<\/p>\n\n\n\n<p>Auch so ein Feld k\u00f6nnen wir lazy initialisieren:<\/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\">BusinessService<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> Settings settings;\n\n  <span class=\"hljs-comment\">\/\/ Not thread-safe!!!<\/span>\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> Settings <span class=\"hljs-title\">getSettings<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ \n    <span class=\"hljs-keyword\">if<\/span> (settings == <span class=\"hljs-keyword\">null<\/span>) {\n      settings = loadSettingsFromDatabase();\n    }\n    <span class=\"hljs-keyword\">return<\/span> settings;\n  }\n\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\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>In einer Spring- oder Jakarta-EE-Anwendung k\u00f6nnten wir die <code>settings<\/code>-Variable auch in einer mit <code>@PostConstruct<\/code> annotierten Methode initialiseren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BusinessService<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> Settings settings;\n\n  <span class=\"hljs-meta\">@PostConstruct<\/span>\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">initializeSettings<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    settings = loadSettingsFromDatabase();\n  }\n\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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>Doch all dies sind Workarounds, und sie haben einige entscheidende Nachteile. Welche das sind, erf\u00e4hrst du im folgenden Abschnitt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"nachteile-der-hausgemachten-lazy-initialization\">Nachteile der \u201ehausgemachten\u201c Lazy Initialization<\/h3>\n\n\n\n<p>Wenn wir uns die Beispiele aus dem vorherigen Abschnitt noch einmal anschauen, dann f\u00e4llt auf: Die Felder <code>logger<\/code> und <code>settings<\/code> sind nicht mehr als <code>final<\/code> gekennzeichnet. Denn das geht nur, wenn sie bei der Deklaration, in einem <code>static<\/code>-Block oder im Konstruktor initialisiert werden.<\/p>\n\n\n\n<p>Das wiederum bedeutet: Wir k\u00f6nnen nicht garantieren, dass die Felder nach der Initialisierung nicht doch noch ver\u00e4ndert werden. Und ohne die Garantie, dass die Werte unver\u00e4nderlich sind, kann die JVM kein Constant Folding durchf\u00fchren.<\/p>\n\n\n\n<p>Au\u00dferdem m\u00fcssen wir \u2013 zumindest bei den ersten zwei Beispielen \u2013 sicherstellen, dass wir auf die Felder nie direkt, sondern immer \u00fcber die <code>getLogger()<\/code> bzw. <code>getSettings()<\/code>-Methode zugreifen.<\/p>\n\n\n\n<p>Und wenn wir uns eben diese Methoden noch einmal anschauen, dann stellen wir fest: Sie sind (bisher) nicht threadsicher! Sie d\u00fcrfen also nicht aus mehreren Threads heraus aufgerufen werden.<\/p>\n\n\n\n<p>Um  die <code>getSettings()<\/code>-Methode thread-safe zu machen, k\u00f6nnten wir sie mit <code>synchronized<\/code> markieren:<\/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-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">synchronized<\/span> Settings <span class=\"hljs-title\">getSettings<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-keyword\">if<\/span> (settings == <span class=\"hljs-keyword\">null<\/span>) {\n    settings = loadSettingsFromDatabase();\n  }\n  <span class=\"hljs-keyword\">return<\/span> settings;\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>Das macht sie zwar threadsicher, gleichzeitig aber auch die Anwendung deutlich langsamer, da nun bei jedem Zugriff auf die Settings der <code>synchronized<\/code>-Block betreten werden muss. <\/p>\n\n\n\n<p>Schneller (aber auch fehleranf\u00e4lliger) ist das sogenannte Double-checked Locking:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">volatile<\/span> Settings settings; <span class=\"hljs-comment\">\/\/ \u27f5 `settings` must be volatile!<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> Settings <span class=\"hljs-title\">getSettings<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  Settings localRef = settings;\n  <span class=\"hljs-keyword\">if<\/span> (localRef == <span class=\"hljs-keyword\">null<\/span>) {\n    <span class=\"hljs-keyword\">synchronized<\/span> (<span class=\"hljs-keyword\">this<\/span>) {\n      localRef = settings;\n      <span class=\"hljs-keyword\">if<\/span> (localRef == <span class=\"hljs-keyword\">null<\/span>) {\n        settings = localRef = loadSettingsFromDatabase();\n      }\n    }\n  }\n  <span class=\"hljs-keyword\">return<\/span> localRef;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><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>Warum du hierbei auf keinen Fall das <code>volatile<\/code> vergessen darfst und welchen Zweck die zus\u00e4tzliche (auf den ersten Blick \u00fcberfl\u00fcssige) Variable <code>localRef<\/code> hat, kannst du im <a href=\"https:\/\/www.happycoders.eu\/de\/java\/double-checked-locking\/\">Artikel \u00fcber das Double-checked Locking Idiom<\/a> nachlesen.<\/p>\n\n\n\n<p>Eine Alternative ist das sogenannte <a href=\"https:\/\/www.happycoders.eu\/de\/java\/initialization-on-demand-holder-idiom\/\">Initialization-on-Demand Holder Idiom<\/a>, bei dem die Tatsache ausgenutzt wird, dass die JVM Klassen zum einen lazy und zum anderen threadsicher l\u00e4dt. Auch das ist ein Workaround. Nicht alle kennen ihn, und er funktioniert nur bei statischen Feldern, nicht bei Instanzfeldern.<\/p>\n\n\n\n<p>Zusammengefasst:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Verz\u00f6gert (\u201elazy\u201c) initialisierte Werte k\u00f6nnen nicht als <code>final<\/code> markiert werden; die Unver\u00e4nderlichkeit ist also nicht garantiert.<\/li>\n\n\n\n<li>Dementsprechend kann die JVM den Code nicht durch Constant Folding optimieren.<\/li>\n\n\n\n<li>Der Aufruf eines verz\u00f6gert initialisierten Wertes muss immer \u00fcber eine Hilfsmethode erfolgen.<\/li>\n\n\n\n<li>In Multithreading-Anwendungen muss diese Hilfsmethode threadsicher sein. Hier k\u00f6nnen sich leicht Fehler einschleichen, was zu subtilen Race Conditions f\u00fchrt.<\/li>\n<\/ol>\n\n\n\n<p>Was uns in Java fehlt, ist ein Mittelweg zwischen <code>final<\/code> und ver\u00e4nderbar. Ein Wert, der dann initialisiert wird, wenn er ben\u00f6tigt wird. Ein Wert, der auf jeden Fall nur einmal initialisiert wird. Und ein Wert, der auch dann korrekt initialisiert wird, wenn aus mehreren Threads auf ihn zugegriffen wird.<\/p>\n\n\n\n<p>Und genau dieser Mittelweg sind Lazy Constants!<\/p>\n\n\n<div class=\"convertkit-form wp-block-convertkit-form\" style=\"\"><script async data-uid=\"1427197203\" src=\"https:\/\/happycoders.kit.com\/1427197203\/index.js\" data-jetpack-boost=\"ignore\" data-no-defer=\"1\" data-no-optimize=\"1\" nowprocket><\/script><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"die-loesung-lazy-constants\">Die L\u00f6sung: Lazy Constants<\/h2>\n\n\n\n<p>Eine Lazy Constant ist ein Container, der ein Objekt enth\u00e4lt, den sogenannten \u201eInhalt\u201c (englisch: \u201econtent\u201c). Eine Lazy Constants wird genau einmal initialisiert, bevor ihr Inhalt abgerufen wird; danach ist sie unver\u00e4nderlich. Eine Lazy Constant ist thread-safe, d. h. wenn auf sie von mehreren Threads aus zugegriffen wird, wird sie maximal einmal initialisiert. Und die JVM kann eine Lazy Constant genauso gut durch Constant Folding optimieren wie ein finales Feld.<\/p>\n\n\n\n<p>Im Folgenden siehst du, wie du das <code>Settings<\/code>-Beispiel mit einer Lazy Constant implementieren kannst.<\/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\">BusinessService<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> LazyConstant&lt;Settings&gt; settings =\n      LazyConstant.of(<span class=\"hljs-keyword\">this<\/span>::loadSettingsFromDatabase);\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Locale <span class=\"hljs-title\">getLocale<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> settings.get().getLocale(); <span class=\"hljs-comment\">\/\/ \u27f5 Here we access the lazy constant<\/span>\n  }\n\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\n}\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>Die an <code>LazyConstant.of()<\/code> \u00fcbergebene Methode \u2013 hier die Methode, die die Settings aus der Datenbank l\u00e4dt \u2013 wird Berechnungsfunktion (\u201eComputing Function\u201c) genannt. Beim ersten Aufruf der <code>get()<\/code>-Methode wird der Inhalt der Lazy Constant einmalig initialisiert, indem die Berechnungsfunktion aufgerufen wird.<\/p>\n\n\n\n<p>Das von <code>of()<\/code> zur\u00fcckgelieferte <code>LazyConstant<\/code>-Objekt k\u00f6nntest du \u00fcbrigens auch in einer Variablen vom Typ <code>Supplier<\/code> speichern, da <code>LazyConstant<\/code> das <code>Supplier<\/code>-Interface erweitert. <\/p>\n\n\n\n<p><code>LazyConstant<\/code> bietet neben <code>get()<\/code> noch zwei weitere Methoden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>isInitialized()<\/code> \u2013 gibt zur\u00fcck, ob der Wert bereits initialisiert wurde.<\/li>\n\n\n\n<li><code>orElse(T other)<\/code> \u2013 gibt den berechneten Wert zur\u00fcck, falls initialisiert, andernfalls <code>other<\/code>. <\/li>\n<\/ul>\n\n\n\n<p>Beide Methoden f\u00fchren <em>nicht<\/em> zu einer Initialisierung der Lazy Constant.<\/p>\n\n\n\n<div class=\"uagb-block-b769b372 uagb-infobox__content-wrap  uagb-infobox-icon-left uagb-infobox-left uagb-infobox-stacked-mobile uagb-infobox-image-valign-top \"><div class=\"uagb-ifb-icon-wrap\"><svg xmlns=\"https:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\"><path d=\"M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z\"><\/path><\/svg><\/div><div class=\"uagb-ifb-content\"><div class=\"uagb-ifb-title-wrap\"><\/div><p class=\"uagb-ifb-desc\">Die Methoden <code>isInitialized()<\/code> und <code>orElse(T other)<\/code> werden <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-27-features\/#lazy-constants-third-preview-jep-531\">in Java 27 wieder entfernt<\/a>.<\/p><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"lazy-lists\">Lazy Lists<\/h3>\n\n\n\n<p>Wir k\u00f6nnen nicht nur <em>einzelne<\/em> Lazy Constants definieren, sondern auch eine <em>Liste<\/em> von Lazy Constants, also eine Liste, bei der jedes einzelne Element erst beim Zugriff darauf \u2013 z. B. mit <code>first()<\/code>, <code>get(int index)<\/code> oder <code>last()<\/code> \u2013 initialisiert wird.<\/p>\n\n\n\n<p>Das folgende Beispiel erzeugt eine Lazy List, in der jedes Element bei dessen ersten Aufruf mit der Quadratwurzel des Listenindexes initialisiert wird:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">List&lt;Double&gt; squareRoots = List.ofLazy(<span class=\"hljs-number\">100<\/span>, Math::sqrt);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><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>Die Gr\u00f6\u00dfe der Liste und deren Elemente sind nicht \u00e4nderbar. Die Methoden <code>add()<\/code>, <code>set()<\/code> und <code>remove()<\/code> f\u00fchren zu einer <code>UnsupportedOperationException<\/code>. Abgeleitete Listen \u2013 z. B. mit <code>subList()<\/code> oder <code>reversed()<\/code> \u2013 sind ebenfalls Lazy Lists.<\/p>\n\n\n\n<p>Hier ein kleines Demo-Programm (ich verwende hier eine <a href=\"https:\/\/www.happycoders.eu\/de\/java\/main-methode\/#vereinfachte-main-methode\">vereinfachte Main-Methode<\/a>, die es ab <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-21-features\/\">Java 21<\/a> als Preview-Feature gibt, und die in <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-25-features\/\">Java 25<\/a> finalisiert wurde):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  List&lt;Double&gt; squareRoots = List.ofLazy(<span class=\"hljs-number\">100<\/span>, i -&gt; {\n    IO.println(<span class=\"hljs-string\">\"Initializing list element at index \"<\/span> + i);\n    <span class=\"hljs-keyword\">return<\/span> Math.sqrt(i);\n  });\n\n  IO.println(<span class=\"hljs-string\">\"squareRoots&#091;0]    = \"<\/span> + squareRoots.get(<span class=\"hljs-number\">0<\/span>));\n  IO.println(<span class=\"hljs-string\">\"squareRoots&#091;1]    = \"<\/span> + squareRoots.get(<span class=\"hljs-number\">1<\/span>));\n  IO.println(<span class=\"hljs-string\">\"squareRoots&#091;2]    = \"<\/span> + squareRoots.get(<span class=\"hljs-number\">2<\/span>));\n  IO.println(<span class=\"hljs-string\">\"squareRoots&#091;0]    = \"<\/span> + squareRoots.get(<span class=\"hljs-number\">0<\/span>));\n  IO.println(<span class=\"hljs-string\">\"squareRoots.first = \"<\/span> + squareRoots.getFirst());\n  IO.println(<span class=\"hljs-string\">\"squareRoots.last  = \"<\/span> + squareRoots.getLast());\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><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>Das Programm gibt folgendes aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Initializing list element at index 0\nsquareRoots&#091;0]    = 0.0\nInitializing list element at index 1\nsquareRoots&#091;1]    = 1.0\nInitializing list element at index 2\nsquareRoots&#091;2]    = 1.4142135623730951\nsquareRoots&#091;0]    = 0.0\nsquareRoots.first = 0.0\nInitializing list element at index 99\nsquareRoots.last  = 9.9498743710662<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><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>Du kannst hier gut erkennen, dass die Lazy List das Element an Position 0 nur einmal berechnet, obwohl es drei Mal abgerufen wird (zwei Mal mit <code>get(0)<\/code> und ein Mal mit <code>getFirst()<\/code>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"lazy-map\">Lazy Map<\/h3>\n\n\n\n<p>Analog zu Lazy Lists k\u00f6nnen wir auch Lazy Maps erzeugen. Bei einer Lazy Map wird f\u00fcr jeden Key der zugeh\u00f6rige Value erst beim ersten Abruf initialisisert und dann gespeichert.<\/p>\n\n\n\n<p>Das folgende Beispiel zeigt eine Lazy Map, mit der wir Lokalisierungsresourcen pro Sprache dynamisch beim ersten Aufruf laden k\u00f6nnen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Set&lt;Locale&gt; supportedLocales = getSupportedLocales();\nMap&lt;Locale, ResourceBundle&gt; resourceBundles =\n    Map.ofLazy(supportedLocales, <span class=\"hljs-keyword\">this<\/span>::loadResourceBundle);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><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>Erst beim ersten Aufruf von <code>resourceBundles.get(...)<\/code> wird das entsprechende Resource Bundle \u00fcber die als Methodenreferenz \u00fcbergebene <code>loadResourceBundle(...)<\/code>-Methode geladen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-funktionieren-lazy-constants-intern\">Wie funktionieren Lazy Constants intern?<\/h2>\n\n\n\n<p>Lazy Constants sind ausschlie\u00dflich im Java-Code implementiert. \u00c4nderungen an Compiler, Bytecode oder JVM waren nicht erforderlich, wie aus dem <a href=\"https:\/\/github.com\/openjdk\/jdk\/pull\/23972\/\" target=\"_blank\" rel=\"noopener\">Pull Request f\u00fcr JEP 502<\/a> hervorgeht.<\/p>\n\n\n\n<p>Der Inhalt einer Lazy Constants wird in einem nicht-finalen Feld gespeichert. Dieses ist mit der JDK-internen Annotation <code>@Stable<\/code> versehen, die auch an anderen Stellen des JDK-Codes zur Optimierung eingesetzt wird. Eben diese Annotation sagt der JVM, dass sich der Wert nach der Initialisierung nicht ein weiteres Mal \u00e4ndern wird. Und so kann die JVM, nachdem der Wert gesetzt wurde, mit der Constant-Folding-Optimierung loslegen.<\/p>\n\n\n\n<p>Die Threadsicherheit wird durch <a href=\"https:\/\/en.wikipedia.org\/wiki\/Memory_barrier\" target=\"_blank\" rel=\"noopener\">Memory Barriers<\/a> sichergestellt, die \u00fcber die <code>Unsafe<\/code>-Klasse gesetzt werden. <\/p>\n\n\n\n<p>Hei\u00dft das, <code>LazyConstant<\/code> ist im Grunde genommen nur ein Wrapper, den wir auch selbst implementieren k\u00f6nnten?<\/p>\n\n\n\n<p>Ja, aber...<\/p>\n\n\n\n<p>Erstens k\u00f6nnen wir weder die JDK-interne <code>@Stable<\/code>-Annotation noch die interne <code>Unsafe<\/code>-Klasse verwenden, ohne diese explizit \u00fcber <code style=\"white-space:nowrap\">--add-exports java.base\/jdk.internal.vm.annotation<\/code> bzw. <code style=\"white-space:nowrap\">--add-exports java.base\/jdk.internal.misc<\/code> unserem Modul zur Verf\u00fcgung zu stellen. <\/p>\n\n\n\n<p>Zweitens <em>sollten<\/em> wir diese JDK-Internals nicht verwenden, da nicht garantiert ist, dass diese sich nicht in einem sp\u00e4teren Java-Release \u00e4ndern werden.<\/p>\n\n\n\n<p>Und drittens schreiben wir ja auch z. B. eine <code>ConcurrentHashMap<\/code> nicht selbst. Dadurch, dass <code>LazyConstant<\/code> von JDK-Spezialisten implementiert wird, k\u00f6nnen wir sichergehen, dass alle nur bekannten Performance-Tricks angewendet wurden und dass auch in Zukunft weitere Performance-Optimierungen vorgenommen werden. Und wenn <code>LazyConstant<\/code> in Zukunft durch Millionen von Java-Entwickler:innen genutzt wird, k\u00f6nnen wir auch sicher sein, dass eventuelle Bugs \u2013 selbst subtile Concurrency-Bugs \u2013 schnell gefunden und behoben werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fazit\"><strong>Fazit<\/strong><\/h2>\n\n\n\n<p><em>Lazy Constants<\/em> sind Konstanten, die zu jeder beliebigen Zeit \u201eon demand\u201c initialisiert werden k\u00f6nnen. Danach sind sie immutable und werden von der JVM genau wie finale Felder behandelt, also z. B. durch Constant Folding optimiert.<\/p>\n\n\n\n<p><em>Lazy Constants<\/em> sind threadsicher, k\u00f6nnen also auch in Multithreading-Programmen eingesetzt werden, ohne subtile Concurrency Bugs zu riskieren.<\/p>\n\n\n\n<p>Neben <em>Lazy Constants<\/em> gibt es <em>Lazy Lists<\/em> und <em>Lazy Maps<\/em>, die die Elemente in Listen und Maps einmalig initialisieren und dann unver\u00e4nderlich speichern.<\/p>\n\n\n\n<p><em>Lazy Constants<\/em> sind als Preview-Feature in <a href=\"https:\/\/jdk.java.net\/25\/\" target=\"_blank\" rel=\"noopener\">Java 25<\/a> (dort noch unter dem Namen \u201eStable Values\u201c) und im aktuellen <a href=\"https:\/\/jdk.java.net\/26\/\" target=\"_blank\" rel=\"noreferrer noopener\">Java 26<\/a> enthalten.<\/p>\n\n\n\n<p>Was h\u00e4lst du von <em>Lazy Constants<\/em>? Teile deine Meinung in den Kommentaren!<\/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 neue 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>Was sind Lazy Constants, und wie benutzt man sie? Was sind Lazy Lists und Lazy Maps? Wie funktionieren Lazy Constants intern?<\/p>\n","protected":false},"author":1,"featured_media":42794,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"Lazy Constants in Java (Stable Values) \u2013 lazy initialisieren","_seopress_titles_desc":"Was sind Lazy Constants (fr\u00fcher: Stable Values) in Java, und wie benutzt man sie? Lazy Lists, Lazy Maps und interne Funktionsweise einfach erkl\u00e4rt.","_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":"","_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":16092,"_post_count":0,"footnotes":""},"categories":[64],"tags":[165],"class_list":["post-42781","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\/04\/java_stable_values_jep502.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/java_stable_values_jep502.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":"Was sind Lazy Constants, und wie benutzt man sie? Was sind Lazy Lists und Lazy Maps? Wie funktionieren Lazy Constants intern?","public_identification_id":"12eb2988124c42afb23582d71d57b291","private_identification_id":"c0831a0016be42cc838a8bb21b7c260d","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42781","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=42781"}],"version-history":[{"count":22,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42781\/revisions"}],"predecessor-version":[{"id":56182,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42781\/revisions\/56182"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/42794"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=42781"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=42781"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=42781"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}