Start / Seminare / Modern Java Development
Modul
Modernes Java verstehen
7 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Modernes Java verstehen
0:00 Java ist alles andere als ein Nischenthema — es trägt Versicherungen, Banken, Industrieanlagen und den Großteil dessen, was im Hintergrund einfach laufen muss. Und genau deshalb ist Java auch die Sprache mit dem größten Altbestand. In vielen Häusern steht Code, der zehn Jahre alt ist und morgen früh trotzdem wieder eine Rechnung schreiben muss.
0:20 In diesem Modul schauen wir uns an, was sich seit damals getan hat. Nicht als Feature-Liste zum Abhaken, sondern mit der Frage im Hinterkopf: Was davon macht Ihren Code tatsächlich besser — und was ist nur neu?
Modernes Java verstehen
0:32 Der erste Tag gehört der Sprache selbst. Wir klären den Releasetakt, sehen uns die wichtigsten Neuerungen seit Java 8 an und entwickeln zum Schluss einen Maßstab dafür, wann sich eine Modernisierung wirklich lohnt. Dieser Maßstab ist wichtiger, als er klingt: Wir brauchen ihn am dritten Tag wieder, wenn ein Coding Agent uns Vorschläge macht und wir entscheiden müssen, welche davon wir annehmen.
0:54 Vier Dinge nehmen Sie aus diesem Modul mit. Erstens ein Gefühl für den Releasetakt, damit Migrationen planbar werden statt überraschend. Zweitens einen Überblick über die Sprachfeatures, die seit Java 8 dazugekommen sind — immer im Kontrast zu dem, was heute in Ihrem Projekt steht. Drittens eine realistische Vorstellung davon, was ein Versionssprung wirklich kostet. Und viertens den erwähnten Maßstab. Was wir hier nicht machen: Java von Grund auf erklären.
1:21 Schleifen und Klassen setzen wir voraus.
Releasemodell und LTS-Strategie
1:25 Fangen wir mit dem Kalender an. Das klingt nach dem langweiligsten Teil des Tages, ist aber der Teil, der über Budgets entscheidet. Denn wer weiß, wann welche Version wie lange gepflegt wird, kann Migrationen einplanen — statt sie als Notfall zu erleben. Und es gibt noch einen zweiten Grund: Der Releasekalender ist der einzige Teil einer Migration, den Sie nicht schätzen müssen. Er steht fest, Jahre im Voraus. Nutzen wir das.
1:51 Java erscheint seit einigen Jahren im festen Takt: immer im März und im September. Stellen Sie sich das wie einen Fahrplan vor — die Bahn fährt, ob Sie einsteigen oder nicht. Die meisten dieser Züge sind Feature-Releases mit sechs Monaten Lebensdauer. Alle zwei Jahre kommt ein Zug, der deutlich länger unterwegs ist: ein LTS-Release mit jahrelanger Pflege.
2:13 Aktuell ist Java 25 dieses LTS, Java 26 das laufende Feature-Release, und im September steht Java 27 an. Für Bestandsprojekte ist die Sache damit einfach: Sie steigen in die LTS-Züge ein, nicht in die dazwischen. Diese Tabelle zeigt nicht einfach Versionsnummern, sondern eine Zeitachse von Verantwortung. Interessant ist die Zeile zu Java 21.
2:36 Viele Teams haben dorthin migriert und sich zurückgelehnt — verständlich, es ist ein LTS. Aber auch LTS-Fenster enden, und dieses endet im September 2026. Das ist kein Gefühl und keine Empfehlung, das ist ein Datum. Wer heute auf 21 steht, hat also nicht mehr Zeit, sondern eine Frist. Und wer noch auf 8 oder 11 steht, hat gleich zwei Sprünge vor sich. Die gute Nachricht: Der Weg ist bekannt, und wir gehen ihn in diesem Seminar.
3:06 Warum sollte Sie ein Releasekalender interessieren, wenn Sie eigentlich Code schreiben wollen? Weil er der einzige Teil der Migration ist, der planbar ist. Alles andere — Abhängigkeiten, Überraschungen, entfernte APIs — kommt später und lässt sich nur schätzen. Der Kalender dagegen steht fest. Wer ihn kennt, kann im Herbst ein Migrationsfenster in die Jahresplanung schreiben, statt im nächsten Frühjahr zu erklären, warum die Sicherheitsupdates ausbleiben.
3:32 Und genau das ist der Unterschied zwischen einer Migration, die stattfindet, und einer, über die man jahrelang spricht. Zwei Missverständnisse begegnen mir immer wieder. Das erste: LTS wird mit „läuft ewig" verwechselt. Tut es nicht — es läuft nur länger. Das zweite ist subtiler: Teams verwechseln den Java-Stand der Laufzeitumgebung mit dem Sprachniveau ihres Codes.
3:55 Sie betreiben die Anwendung längst auf einer aktuellen JVM, schreiben aber weiterhin Java-8-Code, weil die Projektkonfiguration nie nachgezogen wurde. Technisch läuft alles. Fachlich verschenken Sie jede Neuerung der letzten zehn Jahre. Prüfen Sie das ruhig heute Nachmittag einmal in Ihrem eigenen Projekt — die Antwort überrascht öfter, als man denkt.
Vom Java-8-Bestand zum aktuellen LTS
4:17 Damit sind wir bei der eigentlichen Frage: Was passiert, wenn man diesen Sprung wirklich macht? Ich möchte Ihnen hier bewusst nicht die schöne Seite zeigen, sondern die unangenehmen Stellen. Denn wer die kennt, kann schätzen — und wer schätzen kann, bekommt Budget. Wer dagegen mit „so schlimm wird es schon nicht" startet, erlebt die Überraschungen erst im dritten Sprint, wenn die Zusage längst gemacht ist.
4:40 Die häufigste Fehleinschätzung bei einer Java-Migration lautet: Das ist doch nur eine Zahl in der Konfigurationsdatei. Technisch stimmt das sogar — Sie ändern eine Zeile. Aber danach beginnt die Arbeit, und sie liegt selten in Ihrem eigenen Code. Entfernte Pakete, das Modulsystem, veränderte Standardwerte, und vor allem: Bibliotheken, die seit Jahren niemand mehr pflegt. Denken Sie an einen Hausumbau.
5:05 Die neue Wand ist schnell gezogen. Was Zeit kostet, sind die Leitungen, die niemand dokumentiert hat, und der Zulieferer, den es nicht mehr gibt. Der Nutzen dieses Kapitels ist ein sehr praktischer: Sie können hinterher eine Zahl nennen. Nicht auf den Tag genau, aber begründet. Das verändert die Gespräche im Haus erheblich.
5:25 „Wir sollten mal migrieren" ist eine Meinung, die man vertagen kann. „Drei Module sind unkritisch, eines hängt an einer Bibliothek ohne Nachfolger, dafür brauchen wir eine Entscheidung" ist eine Vorlage, mit der jemand arbeiten kann. Und nebenbei erklärt es, warum die dritte Migration im Haus wieder abgebrochen wurde: weil vorher niemand hingesehen hat.
5:46 Diese fünf Schritte haben eine Reihenfolge, und sie ist kein Zufall. Wir erheben zuerst den Stand je Modul, nicht je Projekt — das ist der Punkt, an dem die meisten Schätzungen schon schiefgehen, weil ein Projekt in Wahrheit vier verschiedene Stände hat. Dann kommen die Abhängigkeiten, denn dort steckt der Aufwand. Erst danach der eigene Code. Der wichtigste Schritt ist aber der letzte: die Testabdeckung an den riskanten Stellen.
6:11 Denn er beantwortet nicht die Frage, wie lange es dauert, sondern ob Sie überhaupt sicher migrieren können. Fällt diese Antwort schlecht aus, ändert das den ganzen Plan. Diese vier Punkte haben eines gemeinsam: Sie zeigen sich spät. Ein Werkzeug, das Bytecode manipuliert, scheitert nicht beim Übersetzen, sondern beim Start.
6:30 Reflexion auf JDK-Interna funktioniert jahrelang und wird dann stillschweigend unterbunden. Am tückischsten sind geänderte Standardwerte — da wirft niemand einen Fehler, das Verhalten ist nur ein anderes. Zeichensätze und Zeitzonen sind die Klassiker. Deshalb hilft es wenig, eine Migration am grünen Compiler zu messen. Die interessanten Fragen stellen sich erst zur Laufzeit, und die Antwort darauf geben Tests — womit wir wieder bei Schritt fünf wären.
Records statt Boilerplate
6:57 Jetzt wird es konkreter. Wir sehen uns die Neuerung an, die im Bestand am meisten Code verschwinden lässt — und die zugleich am häufigsten falsch eingesetzt wird. Beides gehört zusammen: Weil der Gewinn so offensichtlich ist, wird sie gern überall angewendet, auch dort, wo sie nicht hingehört. Also schauen wir uns zuerst an, was sie leistet, und danach, wo ihre Grenze liegt.
7:20 Ein Record ist ein Datenträger, mehr nicht. Sie sagen, welche Felder es gibt, und alles Weitere — Konstruktor, Zugriffsmethoden, Vergleich, Textausgabe — entsteht automatisch. Der Vergleich, der mir am besten gefällt: Bisher haben Sie das Formular jedes Mal von Hand abgeschrieben, jetzt füllen Sie nur noch die Felder aus.
7:39 Der eigentliche Gewinn ist aber nicht die Kürze. Es ist die Tatsache, dass Vergleich und Textausgabe garantiert zueinander passen — statt von Hand gepflegt zu werden und nach dem dritten neuen Feld auseinanderzulaufen. Was Sie hier sehen, ist der Anfang. Zwei Felder, ein Konstruktor, und darunter geht es weiter mit Gettern, Vergleich, Streuwert und Textausgabe — der Rest ist aus Platzgründen weggelassen.
8:03 In echten Projekten sind das schnell sechzig Zeilen, von denen keine einzige eine fachliche Entscheidung enthält. Und jede dieser Zeilen ist eine Stelle, an der jemand beim nächsten neuen Feld etwas vergessen kann. Genau das ist der Punkt: Es geht nicht um Tippfaulheit. Es geht darum, dass Code, den niemand liest, trotzdem falsch sein kann.
8:24 Dieselbe Fachlichkeit, drei Zeilen. Was hier fehlt, fehlt nicht — es entsteht beim Übersetzen und ist garantiert konsistent. Wenn Sie zusätzliche Prüfungen brauchen, etwa dass eine Artikelnummer nicht leer sein darf, kommen die in einen kompakten Konstruktor und stehen damit an genau einer Stelle. Das ist der entscheidende Unterschied zur alten Variante: Die fachliche Regel ist sichtbar, weil sie nicht mehr zwischen fünfzig Zeilen Routine versteckt liegt.
8:50 Der stärkste Punkt auf dieser Folie ist der dritte: Unveränderlichkeit ist plötzlich die Voreinstellung. Bisher mussten Sie sich aktiv dafür entscheiden — alle Felder final, keine Setter, Disziplin im Team. Jetzt müssen Sie sich aktiv dagegen entscheiden. Diese Umkehrung wirkt klein und verändert über Jahre das Verhalten eines ganzen Teams. Und sie zahlt sich an einer Stelle aus, an die man zuerst nicht denkt: bei der Fehlersuche.
9:15 Ein Objekt, das sich nicht ändern kann, muss man beim Debuggen auch nicht verfolgen. Der wichtigste Punkt ist der letzte, weil er so leicht übersehen wird. Ein Record schützt die Referenzen, nicht deren Inhalte. Steckt eine Liste im Record, kann niemand die Liste austauschen — aber jeder kann Elemente hineinlegen. Das fühlt sich sicher an und ist es nicht.
9:37 Der andere häufige Fall: der Record mit zehn Feldern. Der ist kein Fortschritt, sondern ein Datenklumpen mit moderner Syntax. Wenn Ihnen beim Schreiben unwohl wird, ist das meist ein Hinweis darauf, dass hier zwei Konzepte in einem Typ stecken. Jetzt sind Sie dran. Suchen Sie sich eine Datenklasse und stellen Sie sie um.
9:56 Der eigentliche Lerneffekt liegt aber nicht im Umbau selbst, sondern in der Beobachtung, wie weit er ausstrahlt: Welche Aufrufstellen haben plötzlich ein Problem? Genau diese Zahl brauchen wir später wieder. Und wenn Sie schnell fertig sind, dreht sich die Aufgabe um: Suchen Sie eine Klasse, die sich bewusst nicht eignet, und begründen Sie, warum.
10:16 Das ist die schwierigere und die nützlichere Übung.
Sealed Types und Pattern Matching
10:20 Im nächsten Kapitel geht es um etwas, das ich für die unterschätzteste Neuerung der letzten Jahre halte. Nicht weil es Code kürzer macht — das tut es kaum. Sondern weil es Fehler von der Laufzeit in den Compiler verschiebt. Und das ist der mit Abstand günstigste Ort, an dem ein Fehler auffallen kann: kein Ticket, kein Betrieb, keine Fehlersuche. Nur eine rote Zeile in der Entwicklungsumgebung.
10:43 Stellen Sie sich eine Gästeliste vor. Ein normales Interface ist eine offene Party — jeder kann erben, Sie wissen nie, wer noch kommt. Ein Sealed Type ist die geschlossene Gesellschaft: Sie legen fest, wer dazugehört. Das klingt nach Einschränkung und ist in Wahrheit ein Geschenk, denn jetzt kann der Compiler mitzählen. Wenn Sie über alle Fälle verzweigen und einer fehlt, sagt er Ihnen das.
11:06 Der vergessene Fall wird zum Übersetzungsfehler — und nicht zu einem Ticket aus dem Betrieb, drei Monate später. Das Muster besteht aus zwei Hälften, die zusammengehören. Oben erklären Sie: Es gibt genau diese drei Bewegungsarten, mehr nicht. Unten verzweigen Sie über alle drei. Und jetzt kommt der interessante Teil — stellen Sie sich vor, nächstes Jahr kommt eine vierte Bewegungsart dazu.
11:30 In der alten Welt hätten Sie im ganzen Projekt suchen müssen, wo überall verzweigt wird, und eine Stelle übersehen. Hier meldet sich der Compiler an genau diesen Stellen. Er wird zu einer Suchmaschine, die nichts vergisst. Der dritte Punkt ist der, der im Alltag am meisten verändert: Fachliche Zustände werden zu Typen statt zu Zeichenketten. Das klingt akademisch, hat aber sehr praktische Folgen.
11:54 Ein Status als Zeichenkette ist eine Verabredung, an die sich alle halten müssen. Ein Status als Typ ist eine Regel, die der Compiler durchsetzt. Der Unterschied zeigt sich immer dann, wenn jemand Neues ins Team kommt, oder wenn Sie selbst nach acht Monaten in den Code zurückkehren und die Verabredung längst vergessen haben.
12:13 Der erste Punkt ist der wichtigste und der ärgerlichste: Ein Default-Zweig hebelt die ganze Prüfung aus. Sie haben sich die Mühe gemacht, die Hierarchie zu schließen, und ein gut gemeintes „für alle anderen Fälle" macht die Sicherheit wieder zunichte — der Compiler schweigt, weil ja alles abgedeckt ist. Meine Empfehlung: In solchen Verzweigungen bewusst auf den Default verzichten und die Lücke lieber vom Compiler zeigen lassen. Es fühlt sich zuerst unbequem an.
12:39 Genau das ist der Sinn.
Switch Expressions und Text Blocks
12:41 Jetzt kommt ein Kapitel mit vielen kleinen Verbesserungen. Einzeln ist keine davon spektakulär, und für sich genommen würde keine eine Umstellung rechtfertigen. In Summe verändern sie allerdings spürbar, wie sich moderner Java-Code liest. Wir gehen sie deshalb zügig durch — mit dem Ziel, dass Sie sie wiedererkennen, wenn Ihnen ein Kollege oder ein Werkzeug sie vorschlägt.
13:03 Zwei Neuerungen, die eine Gemeinsamkeit haben: Sie entfernen eine Fehlerquelle, die es nie hätte geben müssen. Das klassische Switch war eine Anweisungsfolge, bei der man am Ende jedes Zweigs daran denken musste, auszusteigen — und wer es vergaß, bekam ein Verhalten, das niemand wollte. Als Ausdruck gibt es dieses Problem schlicht nicht mehr. Text Blocks lösen dasselbe eine Etage tiefer: mehrzeilige Zeichenketten ohne Escape-Kaskade.
13:29 Wer schon einmal eine Datenbankabfrage mit Anführungszeichen und Zeilenumbrüchen zusammengesetzt hat, weiß, wovon ich rede. Achten Sie auf das, was hier fehlt: kein break, keine vorab deklarierte Variable, die später befüllt wird. Der Switch liefert einen Wert, und dieser Wert wird zugewiesen — das ist als Absicht sofort lesbar.
13:50 Der zweite, weniger sichtbare Gewinn: Der Compiler besteht darauf, dass jeder Zweig einen Wert liefert. Sie können also nicht mehr einen Fall stillschweigend offen lassen. Zusammen mit den abgeschlossenen Typen aus dem letzten Kapitel ergibt das ein sehr enges Netz. Der letzte Punkt ist der, der den Aufwand rechtfertigt: Diese Stellen kommen im Projekt hundertfach vor.
14:12 Eine einzelne Verzweigung umzustellen lohnt sich nicht — das ist reine Kosmetik. Aber wenn Sie ohnehin an einer Klasse arbeiten und die Gelegenheit mitnehmen, summiert sich das über Monate zu spürbar weniger Fehlerfläche. Das ist übrigens ein Muster, das für alle diese Neuerungen gilt: Modernisierung als Nebenprodukt echter Arbeit funktioniert. Modernisierung als eigenes Projekt versandet meistens.
14:35 Der zweite Punkt erwischt fast jeden einmal: Text Blocks nehmen die Einrückung des Quelltextes mit. Sie schreiben den Block schön eingerückt in eine Methode, und die Ausgabe hat plötzlich zwölf Leerzeichen am Zeilenanfang — sichtbar erst dann, wenn die Datenbank die Abfrage nicht mag oder die Datei anders aussieht als erwartet.
14:53 Der dritte Punkt ist eine generelle Warnung: Kürze ist kein Selbstzweck. Ein verschachtelter Ausdruck über sechs Zeilen ist nicht besser als eine ehrliche Verzweigung, er ist nur moderner.
Virtual Threads und Nebenläufigkeit
15:04 Im vorletzten Kapitel geht es um die Neuerung, die am meisten diskutiert wird — und bei der die Erwartungen am weitesten auseinandergehen. Die einen erhoffen sich davon, dass ihre Anwendung schneller wird. Die anderen halten es für einen Nischenfall. Beide liegen daneben. Deshalb klären wir zuerst nüchtern, was Virtual Threads tatsächlich leisten, und danach, wo der Gewinn verpufft.
15:27 Ein klassischer Thread ist teuer, weil das Betriebssystem ihn verwaltet. Deshalb haben wir uns angewöhnt, sie zu sammeln und wiederzuverwenden — Thread-Pools. Virtual Threads dreht das um: Sie sind so günstig, dass Sie einen pro Aufgabe nehmen können, auch bei Zehntausenden. Der Vergleich, der es trifft: Bisher hatten Sie zwanzig Mitarbeiter, die Aufgaben abarbeiten und zwischendurch am Telefon warten.
15:51 Jetzt können Sie für jeden Anruf jemanden abstellen — weil dieser Jemand fast nichts kostet, solange er nur wartet. Wichtig ist der Nachsatz: Rechenleistung kommt dadurch keine hinzu. Das Bemerkenswerte an diesem Code ist, wie unspektakulär er aussieht. Kein Rückruf, kein reaktiver Datenfluss, keine neue Denkweise — eine Schleife, die Aufgaben abgibt.
16:13 Genau das ist der eigentliche Gewinn: Sie schreiben weiterhin geradlinigen, lesbaren Code, der blockiert, wo er auf etwas wartet. Und Sie bekommen trotzdem die Nebenläufigkeit, für die man früher die gesamte Anwendung auf ein reaktives Modell umstellen musste. Für viele Projekte ist das der attraktivere Weg, weil er ohne Umbau der Denkweise auskommt.
16:34 Der dritte Punkt ist der wirtschaftlich interessante: Bestehender blockierender Code kann bleiben, wie er ist. Das unterscheidet diese Neuerung von den meisten anderen Antworten auf Nebenläufigkeit — dort war die Eintrittskarte immer ein Umbau. Hier ist sie eine Konfigurationsentscheidung. Trotzdem eine nüchterne Einordnung: Das ist keine Lösung für zu langsame Anwendungen. Es ist eine Lösung für Anwendungen, die viel warten.
16:59 Wenn Ihr Engpass die Datenbank ist, wird sie es danach immer noch sein — nur werden Sie es deutlicher sehen. Der letzte Punkt ist der, an dem in der Praxis die Ernüchterung einsetzt. Sie stellen auf Virtual Threads um, starten zehntausend Aufgaben — und der Verbindungspool zur Datenbank hat weiterhin zwanzig Plätze. Die Warteschlange ist also nur umgezogen.
17:20 Deshalb lohnt es sich, vor der Umstellung zu klären, wo die echte Obergrenze liegt. Und der erste Punkt ist die technische Falle: Ein synchronisierter Block um einen blockierenden Aufruf kann den darunterliegenden Träger-Thread festhalten. Das ist genau der Fall, den man vermeiden wollte.
Wann ein Feature den Code wirklich verbessert
17:38 Und damit zum letzten Kapitel, das mir persönlich das wichtigste des ganzen Tages ist. Wir haben jetzt viele Möglichkeiten gesehen, und die Versuchung ist groß, sie alle anzuwenden. Jetzt brauchen wir eine Entscheidungshilfe — sonst modernisieren wir alles und verbessern nichts. Dieser Maßstab ist außerdem das Stück aus Modul 1, das uns am dritten Tag wieder begegnet.
18:00 Es gibt eine Versuchung, die jeder kennt, der frisch von einer Schulung kommt: Man will das Neue anwenden. Überall. Sofort. Und ein halbes Jahr später steht im Projekt Code, der modern aussieht und niemandem geholfen hat. Deshalb der nüchterne Satz auf dieser Folie: Eine Änderung lohnt sich, wenn sie einen Fehler unmöglich macht, wenn sie Absicht sichtbarer macht oder wenn sie eine Fehlerquelle entfernt.
18:24 Nicht, wenn sie nur kürzer ist. Kürze ist ein angenehmer Nebeneffekt, aber kein Argument. Die Logik hinter dieser Tabelle ist eine Rangfolge, keine Aufzählung. Ganz oben steht die stärkste Frage: Verhindert es einen Fehler? Wenn ja, brauchen Sie kaum weiter zu diskutieren. Weiter unten wird es schwächer, und die letzte Zeile ist bewusst ein Gegenargument — die Reichweite.
18:46 Eine Änderung, die zweihundert Aufrufstellen berührt, muss deutlich mehr leisten als eine, die eine Klasse betrifft. Und beachten Sie den Hinweis unter der Tabelle: Genau diese Fragen stellen wir am dritten Tag wieder, wenn ein Agent uns Vorschläge macht. Der Maßstab ändert sich nicht dadurch, wer den Vorschlag geschrieben hat.
19:06 Fünf Schritte, und der erste ist der, den man am liebsten überspringt: die Stelle und ihren Zweck verstehen. Das klingt selbstverständlich und wird trotzdem regelmäßig ausgelassen, gerade bei Code, den man selbst nicht geschrieben hat. Interessant ist auch Schritt vier, die Testabdeckung. Denn eine Modernisierung ohne Absicherung ist eine Wette. Manchmal gewinnt man sie. Aber wenn Sie schon wetten, sollten Sie es zumindest wissen.
19:31 Und Schritt fünf lässt ausdrücklich drei Antworten zu — auch „gar nicht" ist ein professionelles Ergebnis. Diese Aufgabe hat einen Nebeneffekt, auf den es mir eigentlich ankommt: Sie arbeiten an Ihrem eigenen Projekt, nicht an unserem Beispiel. Suchen Sie drei Stellen, bewerten Sie sie, und notieren Sie die Entscheidung mitsamt Begründung.
19:51 Wichtig ist wirklich das Notieren — mündliche Einschätzungen überleben den Weg zurück ins Büro selten. Und wenn bei einer der drei Stellen „gar nicht" herauskommt, ist die Aufgabe genauso gelungen. Wir greifen diese Notizen wieder auf, sobald ein Agent uns Vorschläge macht. Ziehen wir zusammen. Sie kennen den Releasetakt und wissen, dass für Java 21 eine Frist läuft.
20:13 Sie wissen, dass der Aufwand einer Migration in den Abhängigkeiten steckt und nicht in der Syntax. Sie haben die Neuerungen gesehen, die Fehler von der Laufzeit zum Compiler verschieben — Records, abgeschlossene Typen, Pattern Matching. Und Sie haben einen Maßstab, der bewertet, ob sich eine Änderung lohnt. Im nächsten Modul verlassen wir die Theorie: Wir sehen uns eine echte Anwendung an, die all diese Altlasten tatsächlich mitbringt.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →