{"id":609,"date":"2025-05-24T00:00:43","date_gmt":"2025-05-23T23:00:43","guid":{"rendered":"https:\/\/www.javaeinfacherkl\u00e4rt.de\/?p=609"},"modified":"2025-06-11T00:06:04","modified_gmt":"2025-06-10T23:06:04","slug":"sealed-classes-in-java-17-kontrollierte-vererbung-fuer-robustere-architekturen","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=609","title":{"rendered":"Sealed Classes in Java 17 \u2013 Kontrollierte Vererbung f\u00fcr robustere Architekturen"},"content":{"rendered":"\n<p>Mit der Ver\u00f6ffentlichung von Java 17 als Long-Term-Support-Version (LTS) hat sich die Sprache um eine Vielzahl moderner Features erweitert, darunter das Konzept der <strong>Sealed Classes<\/strong>. Dieses Feature wurde bereits in Java 15 als Preview eingef\u00fchrt, in Java 16 verbessert und mit Java 17 finalisiert. Sealed Classes bieten eine neue M\u00f6glichkeit, die Vererbung und Implementierung von Klassen, Interfaces und abstrakten Klassen pr\u00e4zise zu steuern. Dadurch lassen sich APIs sicherer gestalten, der Code wird robuster und klarer strukturiert.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Motivation: Warum Sealed Classes?<\/h2>\n\n\n\n<p>Traditionell erlaubt Java eine offene Vererbungshierarchie. Sobald eine Klasse oder ein Interface als <code>public<\/code> und nicht <code>final<\/code> deklariert ist, kann es theoretisch von jedem beliebigen anderen Code erweitert oder implementiert werden \u2013 sofern keine Einschr\u00e4nkungen durch Package-Sichtbarkeit oder <code>final<\/code> bestehen. Das kann in manchen Situationen zu unerw\u00fcnschten Erweiterungen oder zu einer schwer kontrollierbaren API f\u00fchren.<\/p>\n\n\n\n<p>Sealed Classes adressieren genau dieses Problem. Sie erm\u00f6glichen es, die erlaubten Subtypen einer Klasse oder eines Interfaces explizit festzulegen. Das erh\u00f6ht nicht nur die Wartbarkeit und Sicherheit des Codes, sondern verbessert auch die M\u00f6glichkeit zur statischen Analyse und Optimierung durch Werkzeuge oder den Compiler selbst.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Grundlagen: Was ist eine Sealed Class?<\/h2>\n\n\n\n<p>Eine <strong>Sealed Class<\/strong> (versiegelte Klasse) ist eine Klasse oder ein Interface, das explizit angibt, welche Klassen oder Interfaces es <strong>erweitern oder implementieren d\u00fcrfen<\/strong>. Diese erlaubten Subtypen m\u00fcssen entweder im gleichen Modul (bei modularen Projekten) oder im gleichen Paket liegen und die Basisklasse direkt erweitern oder implementieren.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Syntax<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> sealed <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Shape<\/span>\n    <span class=\"hljs-title\">permits<\/span> <span class=\"hljs-title\">Circle<\/span>, <span class=\"hljs-title\">Rectangle<\/span>, <span class=\"hljs-title\">Square<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ ...<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel ist <code>Shape<\/code> eine versiegelte Klasse, und nur <code>Circle<\/code>, <code>Rectangle<\/code> und <code>Square<\/code> d\u00fcrfen sie erweitern.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Anforderungen an Subklassen<\/h2>\n\n\n\n<p>Jeder erlaubte Subtyp muss <strong>eine von drei Entscheidungen treffen<\/strong>:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><code>final<\/code><\/strong> \u2013 Die Klasse kann nicht weitervererbt werden.<\/li>\n\n\n\n<li><strong><code>sealed<\/code><\/strong> \u2013 Die Klasse selbst ist wieder versiegelt und kontrolliert weitere Subtypen.<\/li>\n\n\n\n<li><strong><code>non-sealed<\/code><\/strong> \u2013 Die Klasse hebt die Einschr\u00e4nkung der Vererbung auf; jeder darf sie erweitern.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Beispiele<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Circle<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Shape<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ keine weitere Vererbung m\u00f6glich<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> sealed <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Rectangle<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Shape<\/span>\n    <span class=\"hljs-title\">permits<\/span> <span class=\"hljs-title\">FilledRectangle<\/span>, <span class=\"hljs-title\">EmptyRectangle<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ weitere kontrollierte Vererbung<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> non-sealed <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Square<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Shape<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ offen f\u00fcr beliebige Vererbung<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Verwendung mit Interfaces<\/h2>\n\n\n\n<p>Auch Interfaces k\u00f6nnen versiegelt werden. Das ist besonders hilfreich bei algebraischen Datentypen oder Entwurfsmustern wie dem Visitor-Pattern.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> sealed <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">Expr<\/span> <span class=\"hljs-title\">permits<\/span> <span class=\"hljs-title\">Literal<\/span>, <span class=\"hljs-title\">Addition<\/span>, <span class=\"hljs-title\">Multiplication<\/span> <\/span>{\n    double <span class=\"hljs-keyword\">eval<\/span>();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>So kann der Compiler sicherstellen, dass nur die erlaubten Implementierungen bei Pattern Matching oder instanceof-Pr\u00fcfungen vorkommen.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Vorteile von Sealed Classes<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. <strong>Verbesserte API-Kontrolle<\/strong><\/h3>\n\n\n\n<p>Die Kontrolle dar\u00fcber, welche Klassen eine Basisklasse erweitern d\u00fcrfen, erlaubt es API-Designern, genau festzulegen, wie eine Klasse verwendet werden soll. Das verhindert Missbrauch oder unbeabsichtigte Verwendungen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. <strong>Erh\u00f6hte Sicherheit<\/strong><\/h3>\n\n\n\n<p>Durch Einschr\u00e4nkung der Vererbung kann man verhindern, dass externe Klassen auf intern gedachte Vererbungen zugreifen. Dies erh\u00f6ht die Typsicherheit und Integrit\u00e4t einer Bibliothek oder eines Frameworks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. <strong>Bessere Unterst\u00fctzung f\u00fcr Pattern Matching<\/strong><\/h3>\n\n\n\n<p>In Kombination mit dem neuen Pattern Matching (ebenfalls in Java 17 verbessert) erm\u00f6glichen Sealed Classes eine vollst\u00e4ndige und exakte Analyse der Subtypen. Das verbessert die Lesbarkeit und Wartbarkeit komplexer <code>switch<\/code>-Statements.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. <strong>Statische Erkennung von Unvollst\u00e4ndigkeit<\/strong><\/h3>\n\n\n\n<p>Der Compiler kann erkennen, wenn nicht alle erlaubten Subtypen in einem <code>switch<\/code>-Block behandelt werden. Das reduziert Fehlerquellen und vermeidet unbeabsichtigte Fallthroughs.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Einschr\u00e4nkungen und Regeln<\/h2>\n\n\n\n<p>Sealed Classes unterliegen bestimmten Regeln:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Alle <code>permits<\/code>-Subtypen m\u00fcssen in derselben <strong>Compilation Unit<\/strong>, <strong>im selben Paket<\/strong> oder im selben <strong>Modul<\/strong> definiert sein.<\/li>\n\n\n\n<li>Jeder Subtyp muss die <code>sealed<\/code>, <code>non-sealed<\/code> oder <code>final<\/code>-Deklaration explizit vornehmen.<\/li>\n\n\n\n<li>Anonyme Klassen k\u00f6nnen keine versiegelten Klassen erweitern.<\/li>\n\n\n\n<li>Es kann nur explizit eine \u00fcberschaubare Menge an Subtypen geben \u2013 dynamische Erweiterung zur Laufzeit ist ausgeschlossen.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Praxisbeispiel: Modellierung eines einfachen Ausdrucksbaums<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> sealed <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">Expr<\/span> <span class=\"hljs-title\">permits<\/span> <span class=\"hljs-title\">Value<\/span>, <span class=\"hljs-title\">Add<\/span>, <span class=\"hljs-title\">Multiply<\/span> <\/span>{\n    double <span class=\"hljs-keyword\">eval<\/span>();\n}\n\n<span class=\"hljs-keyword\">public<\/span> record Value(double val) implements Expr {\n    <span class=\"hljs-keyword\">public<\/span> double <span class=\"hljs-keyword\">eval<\/span>() {\n        <span class=\"hljs-keyword\">return<\/span> val;\n    }\n}\n\n<span class=\"hljs-keyword\">public<\/span> record Add(Expr left, Expr right) implements Expr {\n    <span class=\"hljs-keyword\">public<\/span> double <span class=\"hljs-keyword\">eval<\/span>() {\n        <span class=\"hljs-keyword\">return<\/span> left.<span class=\"hljs-keyword\">eval<\/span>() + right.<span class=\"hljs-keyword\">eval<\/span>();\n    }\n}\n\n<span class=\"hljs-keyword\">public<\/span> record Multiply(Expr left, Expr right) implements Expr {\n    <span class=\"hljs-keyword\">public<\/span> double <span class=\"hljs-keyword\">eval<\/span>() {\n        <span class=\"hljs-keyword\">return<\/span> left.<span class=\"hljs-keyword\">eval<\/span>() * right.<span class=\"hljs-keyword\">eval<\/span>();\n    }\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\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel modellieren wir einfache mathematische Ausdr\u00fccke. Dank <code>sealed<\/code> kann der Compiler sicher sein, dass <code>Expr<\/code> nur von <code>Value<\/code>, <code>Add<\/code> und <code>Multiply<\/code> implementiert wird \u2013 was besonders bei der Auswertung hilfreich ist.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Integration mit Pattern Matching (ab Java 17)<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> double <span class=\"hljs-keyword\">eval<\/span>(Expr expr) {\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">switch<\/span> (expr) {\n        <span class=\"hljs-keyword\">case<\/span> Value v -&gt; v.val();\n        <span class=\"hljs-keyword\">case<\/span> Add a -&gt; <span class=\"hljs-keyword\">eval<\/span>(a.left()) + <span class=\"hljs-keyword\">eval<\/span>(a.right());\n        <span class=\"hljs-keyword\">case<\/span> Multiply m -&gt; <span class=\"hljs-keyword\">eval<\/span>(m.left()) * <span class=\"hljs-keyword\">eval<\/span>(m.right());\n    };\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\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Weil alle m\u00f6glichen Implementierungen bekannt sind, kann der Compiler den <code>switch<\/code>-Block pr\u00fcfen und sicherstellen, dass kein Fall vergessen wurde \u2013 ohne <code>default<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p><strong>Sealed Classes<\/strong> in Java 17 sind ein m\u00e4chtiges Werkzeug f\u00fcr die Gestaltung klarer, wartbarer und sicherer APIs. Sie schlie\u00dfen eine L\u00fccke zwischen v\u00f6llig offenen Vererbungshierarchien und starren, <code>final<\/code> deklarierten Klassen. Durch die explizite Kontrolle \u00fcber erlaubte Subtypen lassen sich viele Designprobleme eleganter l\u00f6sen, insbesondere in Kombination mit Pattern Matching und Records.<\/p>\n\n\n\n<p>Wer robuste Architekturen gestalten oder Dom\u00e4nenmodelle pr\u00e4zise abbilden will, sollte die M\u00f6glichkeiten von Sealed Classes unbedingt in Betracht ziehen. Gerade in komplexeren Softwareprojekten \u2013 etwa im Bereich der Compiler-Entwicklung, bei dom\u00e4nenspezifischen Sprachen oder bei API-Designs \u2013 entfalten sie ihr volles Potenzial.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mit der Ver\u00f6ffentlichung von Java 17 als Long-Term-Support-Version (LTS) hat sich die Sprache um eine Vielzahl moderner Features erweitert, darunter das Konzept der Sealed Classes. Dieses Feature wurde bereits in Java 15 als Preview eingef\u00fchrt, in Java 16 verbessert und mit Java 17 finalisiert. Sealed Classes bieten eine neue M\u00f6glichkeit, die Vererbung und Implementierung von [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-609","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/609","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=609"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/609\/revisions"}],"predecessor-version":[{"id":610,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/609\/revisions\/610"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=609"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=609"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}