{"id":53417,"date":"2025-09-03T12:48:05","date_gmt":"2025-09-03T10:48:05","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=53417"},"modified":"2025-11-30T09:12:58","modified_gmt":"2025-11-30T08:12:58","slug":"withers-derived-record-creation","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/withers-derived-record-creation\/","title":{"rendered":"Withers in Java: \u201eDerived Record Creation Expressions\u201c"},"content":{"rendered":"\n<p><em>Derived Record Creation Expressions<\/em> (oder kurz: <em>Withers<\/em>) sind eine pr\u00e4gnante Schreibweise, um von Java-Records abgeleitete Records zu erzeugen, die sich in einem oder mehreren (oder auch keinen) Feldern von dem urspr\u00fcnglichen Record unterscheiden.<\/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>Warum brauchen wir <em>Derived Record Creation Expressions<\/em> (<em>Withers<\/em>)?<\/li>\n\n\n\n<li>Was sind <em>explizite Wither-Methoden<\/em>?<\/li>\n\n\n\n<li>Wie funktionieren <em>Derived Record Creation Expressions<\/em>?<\/li>\n\n\n\n<li>Welche Einschr\u00e4nkungen gelten bei der Verwendung von <em>Derived Record Creation Expressions<\/em>?<\/li>\n<\/ul>\n\n\n\n<p><em>Derived Record Creation Expressions<\/em> werden in einer der kommenden Java-Versionen als Preview-Feature ver\u00f6ffentlicht. Welche Java-Version das sein wird, ist aktuell noch nicht klar, da sich das entsprechende <a href=\"https:\/\/openjdk.org\/jeps\/468\" target=\"_blank\" rel=\"noopener\">JDK Enhancement Proposal 468<\/a> noch im <em>Candidate<\/em>-Status befindet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"warum-brauchen-wir-withers\">Warum brauchen wir Withers?<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-records\/\">Java Records<\/a> sind unver\u00e4nderbar \u2013 und das ist gut so. Denn Unver\u00e4nderbarkeit (Immutability) macht Code verst\u00e4ndlicher, verl\u00e4sslicher und sicherer. Es gibt aber immer wieder Use-Cases, in denen wir von einem bestehenden Record einen neuen Record ableiten wollen, der sich von dem bestehenden Record in nur einem oder einigen Feldern unterscheidet.<\/p>\n\n\n\n<p>Das m\u00f6chte ich dir an einem Beispiel zeigen \u2013 und zwar an folgenden Record:<\/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-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Point3D<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> x, <span class=\"hljs-keyword\">double<\/span> y, <span class=\"hljs-keyword\">double<\/span> z)<\/span> <\/span>{ }<\/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>Nehmen wir an, wir haben einen bestehenden <code>Point3D point<\/code> und wollen nun nur die Z-Koordinate um 10,0 erh\u00f6hen. Dann m\u00fcssen wir wie folgt einen neuen Record erzeugen:<\/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\">Point3D pointNew = <span class=\"hljs-keyword\">new<\/span> Point3D(point.x(), point.y(), point.z() + <span class=\"hljs-number\">10.0<\/span>);<\/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>Wir m\u00fcssen also aus dem bestehenden Record alle Felder auslesen und dann f\u00fcr den neuen Record wiederum alle Felder angeben \u2013 die ge\u00e4nderten und auch die nicht ge\u00e4nderten. Zum einen ist das aufw\u00e4ndig, und zum anderen kann das \u2013 besonders bei komplexeren Records \u2013 schnell fehleranf\u00e4llig werden.<\/p>\n\n\n\n<p>W\u00e4re es nicht sch\u00f6n, wenn wir nur diejenigen Felder angeben m\u00fcssten, die sich ge\u00e4ndert haben?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"bisherige-loesung-explizite-wither-methoden\">Bisherige L\u00f6sung: Explizite Wither-Methoden<\/h2>\n\n\n\n<p>Eine M\u00f6glichkeit, um die Arbeit f\u00fcr die \u201eBenutzer:innen\u201c des Records zu erleichtern, ist die Bereitstellung sogenannter <em>Wither-Methoden<\/em>. Das sind Methoden innerhalb des Records, die einen abgeleiteten Record mit einem (oder mehreren) ge\u00e4nderten Feldern zur\u00fcckliefern.<\/p>\n\n\n\n<p>In unserem <code>Point3D<\/code> k\u00f6nnten wir beispielsweise folgende <em>Wither-Methoden<\/em> zur Verf\u00fcgung stellen:<\/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-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Point3D<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> x, <span class=\"hljs-keyword\">double<\/span> y, <span class=\"hljs-keyword\">double<\/span> z)<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Point3D <span class=\"hljs-title\">withX<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> newX)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Point3D(newX, y, z);\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Point3D <span class=\"hljs-title\">withY<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> newY)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Point3D(x, newY, z);\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Point3D <span class=\"hljs-title\">withZ<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> newZ)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Point3D(x, y, newZ);\n  }\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>Das erm\u00f6glicht es uns nun, die Z-Koordinate wie folgt zu \u00e4ndern:<\/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\">Point3D pointNew = point.withZ(point.z() + <span class=\"hljs-number\">10.0<\/span>);<\/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<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"nachteile-von-expliziten-wither-methoden\">Nachteile von expliziten Wither-Methoden<\/h3>\n\n\n\n<p>Explizite <em>Wither-Methoden<\/em> haben zwei Nachteile. <\/p>\n\n\n\n<p>Der erste ist offensichtlich: <\/p>\n\n\n\n<p>Wir m\u00fcssen eine Menge Boilerplate-Code implementieren, und das stellt einen erh\u00f6hten Implementierungs- und Wartungsaufwand dar. <\/p>\n\n\n\n<p>Der zweite Nachteil: <\/p>\n\n\n\n<p>Falls es semantische Einschr\u00e4nkungen \u00fcber die Kombination mehrerer Felder eines Records gibt, k\u00f6nnen diese Felder ggf. nicht einzeln ge\u00e4ndert werden. Nehmen wir einmal an, die Entfernung unseres <code>Point3D<\/code> vom Ausgangspunkt des Koordinatensystems darf nicht gr\u00f6\u00dfer als 100,0 sein. <\/p>\n\n\n\n<p>Das k\u00f6nnten wir relativ einfach mit folgendem kompakten Konstruktor sicherstellen:<\/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-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Point3D<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> x, <span class=\"hljs-keyword\">double<\/span> y, <span class=\"hljs-keyword\">double<\/span> z)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">public<\/span> Point3D {\n    <span class=\"hljs-keyword\">double<\/span> distance = Math.sqrt(x * x + y * y + z * z);\n    <span class=\"hljs-keyword\">if<\/span> (distance &gt; <span class=\"hljs-number\">100.0<\/span>) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"Point lies outside the allowed distance \"<\/span> +\n                                         <span class=\"hljs-string\">\"of 100 units from origin (0, 0, 0).\"<\/span>);\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>Nehmen wir nun an, wir haben einen Punkt mit den Koordinaten (0, 80, 10) und wollen dessen X- und Y-Koordinaten vertauschen:<\/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\">Point3D point = <span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">80<\/span>, <span class=\"hljs-number\">10<\/span>);\nPoint3D pointNew = point\n    .withX(point.y())\n    .withY(point.x());<\/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>Leider f\u00fchrt das zu einer <code>IllegalArgumentException<\/code>, da im ersten Schritt \u2013 also beim Aufruf von <code>withX(point.y())<\/code> \u2013 versucht wird, einen Punkt mit den Koordinaten (80, 80, 10) zu erstellen.<\/p>\n\n\n\n<p>Wir m\u00fcssten also in <code>Point3D<\/code> eine weitere <em>Wither-Methode<\/em> zur Verf\u00fcgung stellen, die sowohl X- als auch Y-Koordinate setzt (eine sogenannte <em>Compound Wither Method<\/em>):<\/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-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Point3D<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> x, <span class=\"hljs-keyword\">double<\/span> y, <span class=\"hljs-keyword\">double<\/span> z)<\/span> <\/span>{\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Point3D <span class=\"hljs-title\">withXY<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> newX, <span class=\"hljs-keyword\">double<\/span> newY)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Point3D(newX, newY, z);\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>Folgender Aufruf w\u00e4re dann erfolgreich:<\/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\">Point3D point = <span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">80<\/span>, <span class=\"hljs-number\">10<\/span>);\nPoint3D pointNew = point.withXY(point.y(), point.x());<\/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>Falls wir m\u00f6glicherweise andere Koordinatenpaare tauschen wollen, br\u00e4uchten wir entsprechend weitere <em>Wither-Methoden<\/em>. Bei komplexeren Records wird das schnell un\u00fcbersichtlich und fehleranf\u00e4llig.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"die-loesung-derived-record-creation-expressions\">Die L\u00f6sung: Derived Record Creation Expressions<\/h2>\n\n\n\n<p>W\u00e4re es nicht sch\u00f6ner, wenn wir den ganzen Boilerplate-Code vermeiden und uns darauf konzentrieren k\u00f6nnten, anzugeben, welche Record-Komponenten sich auf welche Weise \u00e4ndern sollen?<\/p>\n\n\n\n<p><a href=\"https:\/\/openjdk.org\/jeps\/468\" target=\"_blank\" rel=\"noopener\">JEP 468<\/a> wird mit <em>Derived Record Creation Expressions<\/em> genau das m\u00f6glich machen!<\/p>\n\n\n\n<div class=\"wp-block-uagb-info-box uagb-block-ede8fe70 uagb-infobox__content-wrap  uagb-infobox-icon-left uagb-infobox-left uagb-infobox-stacked-mobile uagb-infobox-image-valign-top hc-infobox\"><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\"><strong>Beachte: <\/strong><br><em>Derived Record Creation Expressions<\/em> sind aktuell noch in keiner Java-Version verf\u00fcgbar, d. h. du musst dich noch etwas gedulden, bis du den folgenden Code ausprobieren kannst.<\/p><\/div><\/div>\n\n\n\n<p>Zun\u00e4chst einmal entfernen wir alle expliziten <em>Wither-Methoden<\/em> aus unserem Record \u2013 der sieht nun wieder wie ganz zu Beginn aus:<\/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-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Point3D<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> x, <span class=\"hljs-keyword\">double<\/span> y, <span class=\"hljs-keyword\">double<\/span> z)<\/span> <\/span>{ }<\/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>Um jetzt z. B. die Z-Koordinate um 10,0 zu erh\u00f6hen, k\u00f6nnen wir ganz einfach das neue <code>with<\/code>-Keyword verwenden:<\/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\">Point3D pointNew = point with {\n  z += <span class=\"hljs-number\">10<\/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>Das bedeutet: \u201eErzeuge einen neuen Record mit <code>z<\/code> um 10,0 erh\u00f6ht\u201c. Dieser Code ist deutlich lesbarer und wartbarer als alles vorherige, da er sich nur auf das fokussiert, was sich \u00e4ndert, und keinen weiteren Boilerplate-Code erfordert.<\/p>\n\n\n\n<p>Noch ein paar weitere Beispiele...<\/p>\n\n\n\n<p><code>x<\/code> und <code>y<\/code> vertauschen k\u00f6nnten wir wie folgt:<\/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\">Point3D pointNew = point with {\n  <span class=\"hljs-keyword\">double<\/span> helper = x;\n  x = y;\n  y = helper;\n};<\/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>Alle Koordinaten mit 2,0 multiplizieren k\u00f6nnten wir so:<\/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\">Point3D pointNew = point with {\n  x *= <span class=\"hljs-number\">2.0<\/span>;\n  y *= <span class=\"hljs-number\">2.0<\/span>;\n  z *= <span class=\"hljs-number\">2.0<\/span>;\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>Wir k\u00f6nnen auch das <code>with<\/code>-Keyword mehrfach aufrufen \u2013 die Multiplikation aller Koordinaten mit 2,0 w\u00e4re auch wie folgt m\u00f6glich:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Point3D pointNew = point \n    with { x *= <span class=\"hljs-number\">2.0<\/span> }\n    with { y *= <span class=\"hljs-number\">2.0<\/span> }\n    with { z *= <span class=\"hljs-number\">2.0<\/span> };<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><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>Aber Achtung: Die letzten zwei Beispiele sind nicht identisch! Im ersten wird <em>ein<\/em> neuer Record erzeugt. Im zweiten werden <em>drei<\/em> neue Records erzeugt \u2013 bei jedem <code>with<\/code>-Aufruf einer. Das ist zum einen mehr Aufwand, und zum anderen k\u00f6nnten dabei Validierungen fehlschlagen, die sich auf die Kombination mehrerer Felder beziehen.<\/p>\n\n\n\n<p>Mehr dazu im n\u00e4chsten Abschnitt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-genau-funktioniert-derived-record-creation\">Wie genau funktioniert Derived Record Creation?<\/h3>\n\n\n\n<p>Ich werde die genaue Funktionsweise von <em>Derived Record Creation Expressions<\/em> am ersten <code>with<\/code>-Beispiel von oben erkl\u00e4ren \u2013 hier ist es noch einmal:<\/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\">Point3D pointNew = point with {\n  z += <span class=\"hljs-number\">10<\/span>;\n};<\/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>Eine <em>Derived Record Creation Expression<\/em> besteht aus drei Teilen:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>der <em>Origin Expression<\/em> (dem \u201eUrsprungsausdruck\u201c) \u2013 im Beispiel: <code>point<\/code><\/li>\n\n\n\n<li>dem Keyword <code>with<\/code><\/li>\n\n\n\n<li>dem <em>Transformation Block<\/em> \u2013 im Beispiel: <code>{ z += 10; }<\/code><\/li>\n<\/ol>\n\n\n\n<p>Innerhalb des Transformationsblocks werden alle Felder des urspr\u00fcnglichen Records durch Aufruf von dessen Accessor-Methoden in lokalen, \u00e4nderbaren Variablen bereitgestellt. Es ist so, als w\u00fcrde vor der Ausf\u00fchrung des Transformationsblocks folgender Code ausgef\u00fchrt werden:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">double<\/span> x = x();\n<span class=\"hljs-keyword\">double<\/span> y = y();\n<span class=\"hljs-keyword\">double<\/span> z = z();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><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>Es wird also nicht direkt auf die Felder zugegriffen: Sollten die Accessor-Methoden \u00fcberschrieben worden sein und weitere Logik enthalten, so wird diese ausgef\u00fchrt.<\/p>\n\n\n\n<p>Dann wird der Transformationsblock ausgef\u00fchrt \u2013 im Beispiel also die lokale Variable <code>z<\/code> um 10,0 erh\u00f6ht.<\/p>\n\n\n\n<p>Am Ende des Transformationsblocks wird ein neuer Record anhand der (m\u00f6glicherweise ver\u00e4nderten) lokalen Variablen erzeugt, also so:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">new<\/span> Point3D(x, y, z)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><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>Dabei wird auch tats\u00e4chlich der Record-Konstruktor aufgerufen, um dort m\u00f6glicherweise vorhandene Validierungen auszuf\u00fchren.<\/p>\n\n\n\n<p>Damit verstehst du auch, warum die letzten beiden Beispiele des vorherigen Abschnitts unterschiedlich sind: Beim einmaligen Aufruf von <code>with<\/code> wird der Konstruktor <em>einmal<\/em> aufgerufen \u2013 mit <em>allen<\/em> \u00c4nderungen. Beim mehrmaligen Aufruf von <code>with<\/code> wird der Konstruktor <code>mehrfach<\/code> aufgerufen \u2013 jeweils mit nur einer \u00c4nderung. So w\u00fcrden Validierungen, die sich auf die Kombination mehrerer Parameter beziehen, bei einem ung\u00fcltigen Zwischenzustand fehlschlagen.<\/p>\n\n\n\n<p>Hier noch einige Hinweise: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sollte der urspr\u00fcngliche Ausdruck \u2013 im Beispiel also <code>point<\/code> \u2013 <code>null<\/code> sein, kommt es zu einer <code>NullPointerException<\/code>.<\/li>\n\n\n\n<li>Der Transformationsblock darf auch leer sein \u2013 in dem Fall wird eine unver\u00e4nderte Kopie des urspr\u00fcnglichen Records zur\u00fcckgegeben.<\/li>\n\n\n\n<li>Falls au\u00dferhalb der <em>Derived Record Creation Expression<\/em> eine Variable existiert mit demselben Namen wie ein Feld des Records, dann ist diese innerhalb des Transformationsblocks nicht sichtbar (sie ist \u201egeshadowed\u201c).<\/li>\n<\/ul>\n\n\n\n<p>Hier ist der dritte Punkt nochmal an einem Beispiel erkl\u00e4rt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">double<\/span> x = <span class=\"hljs-number\">50<\/span>;\n\nPoint3D point = <span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">20<\/span>, <span class=\"hljs-number\">30<\/span>);\nPoint3D pointNew = point with {\n  <span class=\"hljs-comment\">\/\/ x is 10 here, not 50.<\/span>\n  <span class=\"hljs-comment\">\/\/ The \"outer\" x is not visible here.<\/span>\n  x = <span class=\"hljs-number\">20<\/span>;\n}\n\n<span class=\"hljs-comment\">\/\/ x is 50 here, not 20.<\/span>\n<span class=\"hljs-comment\">\/\/ The \"inner\" x is not visible here.<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><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<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"verschachtelte-derived-record-creation\">Verschachtelte Derived Record Creation<\/h3>\n\n\n\n<p>Bei ineinander verschachtelten Records k\u00f6nnen auch die <code>with<\/code>-Ausdr\u00fccke verschachtelt werden. Der folgende Record definiert eine Linie im dreidimensionalen Raum:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Line3D<\/span><span class=\"hljs-params\">(Point3D start, Point3D end)<\/span> <\/span>{ }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><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>Legen wir einmal eine solche Linie an:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Line3D line = <span class=\"hljs-keyword\">new<\/span> Line3D(<span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>), <span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">6<\/span>));<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><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>Dann k\u00f6nnten wir jetzt z. B. den Endpunkt wie folgt \u00e4ndern (noch nicht verschaltelt):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">line = line with { \n  end = <span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">10<\/span>); \n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><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>Der neue Endpunkt unterscheidet sich nur in der Z-Koordinate vom urspr\u00fcnglichen Endpunkt. Das k\u00f6nnen wir auch wie folgt \u2013 mit verschachtelten <code>with<\/code>-Ausdr\u00fccken \u2013 pr\u00e4gnanter schreiben:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">line = line with { \n  end = end with { z = <span class=\"hljs-number\">10<\/span>; }\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><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<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"innere-derived-record-creation\">Innere Derived Record Creation<\/h3>\n\n\n\n<p><em>Derived Record Creation Expressions<\/em> d\u00fcrfen auch <em>innerhalb<\/em> des Records eingesetzt werden. Beispielsweise k\u00f6nnten wir f\u00fcr den <code>Point3D<\/code>-Record eine Skalierungsmethode anbieten:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Point3D<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> x, <span class=\"hljs-keyword\">double<\/span> y, <span class=\"hljs-keyword\">double<\/span> z)<\/span> <\/span>{\n  <span class=\"hljs-comment\">\/\/ . . .<\/span>\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Point3D <span class=\"hljs-title\">scale<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">double<\/span> factor)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">this<\/span> with {\n      x *= factor;\n      y *= factor;\n      z *= factor;\n    };    \n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><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<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"einschraenkungen-von-derived-record-creation-expressions\">Einschr\u00e4nkungen von Derived Record Creation Expressions<\/h3>\n\n\n\n<p>F\u00fcr <em>Derived Record Creation Expressions<\/em> gelten folgende Einschr\u00e4nkungen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Der Transformationsblock darf keinen <code>return<\/code>-Ausdruck enthalten.<\/li>\n\n\n\n<li>Der Transformationsblock darf keinen <code>yield<\/code>-, <code>break<\/code>- oder <code>continue<\/code>-Ausdruck enthalten, dessen Ziel au\u00dferhalb des Transformationsblocks liegt.<\/li>\n<\/ul>\n\n\n\n<p>Den zweiten Punkt erkl\u00e4re ich auch noch einmal an einem Beispiel. <\/p>\n\n\n\n<p>Erlaubt ist z. B. der folgende (zugegebenerma\u00dfen stark konstruierte) Code, in dem die Ziele von <code>yield<\/code> und <code>break<\/code> <em>innerhalb<\/em> des Transformationsblocks liegen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Point3D point = <span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">20<\/span>, <span class=\"hljs-number\">30<\/span>);\nPoint3D pointNew = point with {\n  y = <span class=\"hljs-keyword\">switch<\/span> (x) {\n    <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-keyword\">double<\/span> d when d &lt; <span class=\"hljs-number\">0.0<\/span> -&gt; -<span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-keyword\">double<\/span> d when d &gt; <span class=\"hljs-number\">0.0<\/span> -&gt; {\n      <span class=\"hljs-keyword\">double<\/span> newValue = d;\n      <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n        newValue *= <span class=\"hljs-number\">2.0<\/span>;\n        <span class=\"hljs-keyword\">if<\/span> (newValue &gt; <span class=\"hljs-number\">100.0<\/span>) <span class=\"hljs-keyword\">break<\/span>;  <span class=\"hljs-comment\">\/\/ allowed<\/span>\n      }\n      yield newValue;  <span class=\"hljs-comment\">\/\/ allowed<\/span>\n    }\n    <span class=\"hljs-keyword\">default<\/span> -&gt; <span class=\"hljs-number\">0<\/span>;\n  };\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><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>Folgender (ebenso stark konstruierter) Code hingegen w\u00e4re <em>nicht<\/em> erlaubt, da hier das Ziel von <code>break<\/code> die <code>for<\/code>-Schleife au\u00dferhalb der <em>Derived Record Creation Expression<\/em> w\u00e4re:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Point3D point = <span class=\"hljs-keyword\">new<\/span> Point3D(<span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">20<\/span>, <span class=\"hljs-number\">30<\/span>);\n<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n  point = point with {\n    <span class=\"hljs-keyword\">if<\/span> (x &gt; <span class=\"hljs-number\">0.0<\/span>) {\n      x -= <span class=\"hljs-number\">1.0<\/span>;\n    } <span class=\"hljs-keyword\">else<\/span> {\n      <span class=\"hljs-keyword\">break<\/span>;  <span class=\"hljs-comment\">\/\/ not allowed<\/span>\n    }\n  };\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><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<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fazit\">Fazit<\/h2>\n\n\n\n<p><em>Derived Record Creation Expressions<\/em> sind eine pr\u00e4gnante Syntax, um abgeleitete Records zu erstellen und dabei nur die ge\u00e4nderten Felder zu spezifizieren \u2013 ohne daf\u00fcr selbst explizite, wartungsintensive Wither-Methoden schreiben zu m\u00fcssen.<\/p>\n\n\n\n<p>Aktuell ist leider noch nicht abzusehen, wann <em>Derived Record Creation<\/em> verf\u00fcgbar sein wird \u2013 sobald sich das \u00e4ndert, wirst du es hier fr\u00fchzeitig erfahren.<\/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>Lerne, wie Withers (Derived Record Creation Expressions) Java-Records vereinfachen, Boilerplate vermeiden und die Arbeit mit immutablen Daten erleichtern.<\/p>\n","protected":false},"author":1,"featured_media":53481,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"","_seopress_titles_desc":"Lerne, wie Withers (Derived Record Creation Expressions) Java-Records vereinfachen, Boilerplate vermeiden und die Arbeit mit immutablen Daten erleichtern.","_seopress_robots_index":"","_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":12467,"_post_count":0,"footnotes":""},"categories":[64],"tags":[179],"class_list":["post-53417","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-amber-de"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/09\/java-withers-derived-record-creation.v4.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":"Lerne, wie Withers (Derived Record Creation Expressions) Java-Records vereinfachen, Boilerplate vermeiden und die Arbeit mit immutablen Daten erleichtern.","public_identification_id":"a41883406d4c4dc5ac32b3e6d6d4fa4f","private_identification_id":"b74e9e2f7e754b99b8f8d7f287fdeb2b","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/53417","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=53417"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/53417\/revisions"}],"predecessor-version":[{"id":53486,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/53417\/revisions\/53486"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/53481"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=53417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=53417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=53417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}