{"id":429,"date":"2024-06-05T22:09:56","date_gmt":"2024-06-05T21:09:56","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=429"},"modified":"2024-06-26T22:11:39","modified_gmt":"2024-06-26T21:11:39","slug":"einfuehrung-in-die-java-generics","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=429","title":{"rendered":"Einf\u00fchrung in die Java Generics"},"content":{"rendered":"\n<p>Java Generics, eingef\u00fchrt in JDK 5.0, sind ein m\u00e4chtiges Werkzeug zur Erh\u00f6hung der Typensicherheit und Lesbarkeit von Code. Generics erm\u00f6glichen es, Klassen, Schnittstellen und Methoden zu erstellen, die mit beliebigen Typen arbeiten k\u00f6nnen, ohne dass dabei auf Typpr\u00fcfung zur Laufzeit (type casting) zur\u00fcckgegriffen werden muss. Dieser Artikel gibt eine umfassende Einf\u00fchrung in die Grundlagen von Java Generics, einschlie\u00dflich ihrer Syntax, Verwendung und der h\u00e4ufigsten Anwendungsf\u00e4lle.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Die Motivation hinter Generics<\/h3>\n\n\n\n<p>Vor der Einf\u00fchrung von Generics war die Typensicherheit in Java durch Typpr\u00fcfung zur Laufzeit gew\u00e4hrleistet, was zu un\u00fcbersichtlichem und fehleranf\u00e4lligem Code f\u00fchren konnte. Ein typisches Beispiel war die Verwendung von <code>Collections<\/code>, bei denen die enthaltenen Elemente als <code>Object<\/code> behandelt wurden. Dies erforderte Typumwandlungen (casts), die zur Laufzeit fehlschlagen konnten.<\/p>\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\">List<\/span> <span class=\"hljs-keyword\">list<\/span> = <span class=\"hljs-keyword\">new<\/span> ArrayList();\n<span class=\"hljs-keyword\">list<\/span>.add(<span class=\"hljs-string\">\"Hallo\"<\/span>);\nString s = (String) <span class=\"hljs-keyword\">list<\/span>.get(<span class=\"hljs-number\">0<\/span>); <span class=\"hljs-comment\">\/\/ Typumwandlung notwendig<\/span><\/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>Dieses Muster ist fehleranf\u00e4llig, da eine falsche Typumwandlung zu <code>ClassCastException<\/code> f\u00fchren kann. Generics wurden eingef\u00fchrt, um diese Probleme zu l\u00f6sen und den Code sicherer und lesbarer zu machen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Grundlegende Syntax von Generics<\/h3>\n\n\n\n<p>Generics erm\u00f6glichen es, Klassen, Schnittstellen und Methoden zu parametrisieren. Ein einfaches Beispiel ist die Verwendung von Generics in der <code>List<\/code>-Schnittstelle:<\/p>\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\">List<\/span>&lt;String&gt; <span class=\"hljs-keyword\">list<\/span> = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n<span class=\"hljs-keyword\">list<\/span>.add(<span class=\"hljs-string\">\"Hallo\"<\/span>);\nString s = <span class=\"hljs-keyword\">list<\/span>.get(<span class=\"hljs-number\">0<\/span>); <span class=\"hljs-comment\">\/\/ Keine Typumwandlung notwendig<\/span><\/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<p>In diesem Fall ist <code>List&lt;String&gt;<\/code> eine generische Listenschnittstelle, die nur <code>String<\/code>-Objekte akzeptiert. Dies erh\u00f6ht die Typensicherheit, da zur Kompilierzeit \u00fcberpr\u00fcft wird, dass nur <code>String<\/code>-Objekte hinzugef\u00fcgt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Verwendung von Generics in Klassen und Methoden<\/h3>\n\n\n\n<p>Generische Klassen und Methoden sind der Kern der Generics in Java. Hier ist ein Beispiel f\u00fcr eine generische Klasse:<\/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> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Box<\/span>&lt;<span class=\"hljs-title\">T<\/span>&gt; <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> T content;\n\n    <span class=\"hljs-keyword\">public<\/span> void setContent(T content) {\n        this.content = content;\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> T getContent() {\n        <span class=\"hljs-keyword\">return<\/span> content;\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>In diesem Beispiel ist <code>Box<\/code> eine generische Klasse mit einem Typparameter <code>T<\/code>. Dieser Typparameter kann zur Kompilierzeit durch einen beliebigen Typ ersetzt werden.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Box&lt;<span class=\"hljs-built_in\">String<\/span>&gt; stringBox = <span class=\"hljs-keyword\">new<\/span> Box&lt;&gt;();\nstringBox.setContent(<span class=\"hljs-string\">\"Hello\"<\/span>);\n<span class=\"hljs-built_in\">String<\/span> content = stringBox.getContent();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Generische Methoden<\/h3>\n\n\n\n<p>Neben generischen Klassen k\u00f6nnen auch Methoden generisch sein. Eine generische Methode wird durch Hinzuf\u00fcgen eines Typparameters vor dem R\u00fcckgabewert deklariert:<\/p>\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> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Utils<\/span> <\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> &lt;T&gt; void printArray(T&#91;] <span class=\"hljs-keyword\">array<\/span>) {\n        <span class=\"hljs-keyword\">for<\/span> (T element : <span class=\"hljs-keyword\">array<\/span>) {\n            System.out.println(element);\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>Hier ist <code>printArray<\/code> eine generische Methode, die ein Array eines beliebigen Typs akzeptiert und dessen Elemente ausgibt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Einschr\u00e4nkungen und Beschr\u00e4nkungen von Generics<\/h3>\n\n\n\n<p>Generics bieten viele Vorteile, aber sie haben auch einige Einschr\u00e4nkungen. Eine der wichtigsten ist die Typl\u00f6schung (type erasure). W\u00e4hrend der Kompilierung werden alle generischen Typen entfernt und durch ihre Bound-Typen (oder <code>Object<\/code> wenn keine Bounds definiert sind) ersetzt. Dies bedeutet, dass Generics zur Laufzeit nicht mehr verf\u00fcgbar sind und daher keine Instanzen von generischen Typen erstellt werden k\u00f6nnen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" 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-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">GenericClass<\/span>&lt;<span class=\"hljs-title\">T<\/span>&gt; <\/span>{\n    <span class=\"hljs-comment\">\/\/ Kompiliert nicht<\/span>\n    <span class=\"hljs-comment\">\/\/ T instance = new T();<\/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\">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>Auch ist es nicht m\u00f6glich, Arrays von parametrisierten Typen zu erstellen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">List&lt;<span class=\"hljs-built_in\">String<\/span>&gt;&#91;] arrayOfLists = <span class=\"hljs-keyword\">new<\/span> List&lt;<span class=\"hljs-built_in\">String<\/span>&gt;&#91;<span class=\"hljs-number\">10<\/span>]; <span class=\"hljs-comment\">\/\/ Kompiliert nicht<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Wildcards und bounded Type Parameters<\/h3>\n\n\n\n<p>Java Generics bieten Wildcards (<code>?<\/code>) und begrenzte Typparameter (bounded type parameters), um flexibler mit Typen umgehen zu k\u00f6nnen.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ungebundene Wildcards<\/h4>\n\n\n\n<p>Eine ungebundene Wildcard (<code>?<\/code>) kann jeden beliebigen Typ repr\u00e4sentieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">List<\/span><span class=\"hljs-meta\">&lt;?<\/span>&gt; <span class=\"hljs-keyword\">list<\/span> = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;String&gt;();\n<span class=\"hljs-keyword\">list<\/span> = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;Integer&gt;();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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<h4 class=\"wp-block-heading\">Gebundene Wildcards<\/h4>\n\n\n\n<p>Gebundene Wildcards erm\u00f6glichen es, den Bereich der akzeptierten Typen einzuschr\u00e4nken:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> void process(<span class=\"hljs-keyword\">List<\/span><span class=\"hljs-meta\">&lt;?<\/span> extends Number&gt; <span class=\"hljs-keyword\">list<\/span>) {\n    <span class=\"hljs-comment\">\/\/ Verarbeitet Listen von Number oder deren Unterklassen<\/span>\n}\n\n<span class=\"hljs-keyword\">List<\/span>&lt;Integer&gt; intList = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\nprocess(intList); <span class=\"hljs-comment\">\/\/ Funktioniert<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><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 akzeptiert <code>process<\/code> nur Listen von <code>Number<\/code> oder deren Unterklassen (<code>Integer<\/code>, <code>Double<\/code> usw.).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Typinferenz<\/h3>\n\n\n\n<p>Java unterst\u00fctzt Typinferenz, um die Typen in generischen Methoden und Konstruktoren automatisch zu ermitteln. Dies reduziert die Notwendigkeit, explizite Typen anzugeben:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">Box<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Integer<\/span>&gt;<\/span> box = new Box<span class=\"hljs-tag\">&lt;&gt;<\/span>();\nbox.setContent(123);\n\nBox<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Integer<\/span>&gt;<\/span> inferredBox = Box.of(123); \/\/ Annahme: Box hat eine statische Methode of<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Praxisbeispiele<\/h3>\n\n\n\n<p>Generics sind weit verbreitet in der Java-Standardbibliothek. Einige h\u00e4ufige Anwendungsf\u00e4lle sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Collections API<\/strong>: <code>List&lt;E><\/code>, <code>Map&lt;K, V><\/code>, <code>Set&lt;E><\/code><\/li>\n\n\n\n<li><strong>Java Streams API<\/strong>: <code>Stream&lt;T><\/code><\/li>\n\n\n\n<li><strong>Future und CompletableFuture<\/strong>: <code>Future&lt;V><\/code>, <code>CompletableFuture&lt;T><\/code><\/li>\n<\/ul>\n\n\n\n<p>Hier ist ein erweitertes Beispiel zur Verwendung von Generics in einer benutzerdefinierten Datenstruktur:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">public <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Pair<\/span>&lt;<span class=\"hljs-title\">K<\/span>, <span class=\"hljs-title\">V<\/span>&gt; <\/span>{\n    private K key;\n    private V value;\n\n    public Pair(K key, V value) {\n        <span class=\"hljs-keyword\">this<\/span>.key = key;\n        <span class=\"hljs-keyword\">this<\/span>.value = value;\n    }\n\n    public K getKey() {\n        <span class=\"hljs-keyword\">return<\/span> key;\n    }\n\n    public V getValue() {\n        <span class=\"hljs-keyword\">return<\/span> value;\n    }\n\n    public <span class=\"hljs-keyword\">void<\/span> setKey(K key) {\n        <span class=\"hljs-keyword\">this<\/span>.key = key;\n    }\n\n    public <span class=\"hljs-keyword\">void<\/span> setValue(V value) {\n        <span class=\"hljs-keyword\">this<\/span>.value = value;\n    }\n}\n\nPair&lt;<span class=\"hljs-built_in\">String<\/span>, Integer&gt; pair = <span class=\"hljs-keyword\">new<\/span> Pair&lt;&gt;(<span class=\"hljs-string\">\"One\"<\/span>, <span class=\"hljs-number\">1<\/span>);\n<span class=\"hljs-built_in\">String<\/span> key = pair.getKey();\nInteger value = pair.getValue();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Schlussfolgerung<\/h3>\n\n\n\n<p>Java Generics sind ein essenzielles Feature, das die Typensicherheit und Lesbarkeit des Codes erheblich verbessert. Durch die Einf\u00fchrung von Typparametern, Wildcards und bounded Type Parameters bieten Generics eine hohe Flexibilit\u00e4t und Wiederverwendbarkeit von Code. Trotz einiger Einschr\u00e4nkungen, wie der Typl\u00f6schung, sind Generics ein m\u00e4chtiges Werkzeug, das in vielen Bereichen der Java-Programmierung unverzichtbar geworden ist. Durch das Verst\u00e4ndnis und die richtige Anwendung von Generics k\u00f6nnen Entwickler robustere und sicherere Java-Anwendungen schreiben.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Java Generics, eingef\u00fchrt in JDK 5.0, sind ein m\u00e4chtiges Werkzeug zur Erh\u00f6hung der Typensicherheit und Lesbarkeit von Code. Generics erm\u00f6glichen es, Klassen, Schnittstellen und Methoden zu erstellen, die mit beliebigen Typen arbeiten k\u00f6nnen, ohne dass dabei auf Typpr\u00fcfung zur Laufzeit (type casting) zur\u00fcckgegriffen werden muss. Dieser Artikel gibt eine umfassende Einf\u00fchrung in die Grundlagen 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-429","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\/429","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=429"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/429\/revisions"}],"predecessor-version":[{"id":430,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/429\/revisions\/430"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}