{"id":3107,"date":"2019-08-14T09:00:40","date_gmt":"2019-08-14T07:00:40","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=3107"},"modified":"2025-12-15T10:53:41","modified_gmt":"2025-12-15T09:53:41","slug":"besseren-code-schreiben-statische-code-analyse","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/besseren-code-schreiben-statische-code-analyse\/","title":{"rendered":"Besseren Code schreiben mit Statischer Code-Analyse"},"content":{"rendered":"\n<p>Vor vielen Jahren, als ich mich \u2013 unerfahren und naiv wie ich war \u2013 f\u00fcr einen deutlich besseren Programmierer hielt als ich es damals war, fragte mich jemand: \"Sven, wie viele Zeilen hat Deine l\u00e4ngste Methode?\" Ich wusste weder eine Antwort auf die Frage noch verstand ich deren Hintergrund. Heute kann ich die Frage im Schlaf beantworten: 50! Sicher stellen wir das mit Checkstyle (mehr dazu unten) und wichtig ist das, da somit alle (ohne Ausnahme!) unserer Methoden ohne zu Scrollen auf den Bildschirm passen und so deren Funktion sehr schnell erfasst werden kann.<\/p>\n\n\n\n<p>Im <a href=\"https:\/\/www.happycoders.eu\/de\/java\/hochwertigen-code-schreiben-java-code-standards-durchsetzen\/\">ersten Teil dieser Artikelserie<\/a> \u00fcber Statische Code-Analyse habe ich die folgenden qualitativen Ziele bei der Softwareentwicklung aufgelistet:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sicherstellung eines einheitlichen Code-Stils im Team,<\/li>\n\n\n\n<li>Entwicklung von lesbarem und wartbarem Code,<\/li>\n\n\n\n<li>Entwicklung von m\u00f6glichst fehlerfreiem Code,<\/li>\n\n\n\n<li>Minimierung von Sicherheitsl\u00fccken in der Software.<\/li>\n<\/ul>\n\n\n\n<p>Klassischerweise versuchen IT-Teams durch regelm\u00e4\u00dfige Code-Reviews diesen Zielen m\u00f6glichst nah zu kommen. Dieser Teil der Serie erkl\u00e4rt, wie Statische Code-Analyse die Erreichung der oben genannten Ziele im Einzelnen f\u00f6rdern kann.<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Wie Statische Code-Analyse helfen kann<\/h2>\n\n\n\n<p>Entsprechend der vier oben genannten Ziele kann man die Aufgaben f\u00fcr Statische Code-Analyse-Tools in folgende Kategorien aufteilen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u00dcberpr\u00fcfung des Code-Standards,<\/li>\n\n\n\n<li>Berechnung von Softwaremetriken,<\/li>\n\n\n\n<li>Erkennung von Fehlern im Code,<\/li>\n\n\n\n<li>Erkennung von Sicherheitsl\u00fccken.<\/li>\n<\/ul>\n\n\n\n<p>Ein zus\u00e4tzlicher Querschnittsaspekt ist die Fortschritts\u00fcberwachung, d. h. die Speicherung von Metriken verschiedener Tools \u00fcber die Zeit. Dadurch wird nachverfolgbar, ob sich die Code-Qualit\u00e4t im Hinblick auf die konfigurierten Aspekte verbessert oder verschlechtert.<\/p>\n\n\n\n<p>Im Folgenden gehe ich detailliert auf die Kategorien ein.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00dcberpr\u00fcfung des Code-Standards<\/h2>\n\n\n\n<p>Tools dieser Kategorie pr\u00fcfen, ob der Quellcode vorher festgelegten und konfigurierten Code-Formatierungsvorgaben entspricht. Dabei k\u00f6nnen Aspekte wie bspw. Klammersetzung, Einr\u00fcckung, Zeilenbreite, Leerzeichen und -zeilen, Klassen- und Methodenl\u00e4ngen, Anzahl von Methodenparametern und vieles weitere mehr \u00fcberpr\u00fcft werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Warum ist einheitlicher Code-Standard wichtig?<\/h3>\n\n\n\n<p>Einheitlicher Code-Standard hat folgende Vorteile:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Einheitlich formatierten Code ist einfacher zu lesen und zu verstehen.<\/li>\n\n\n\n<li>Wenn alle Entwickler direkt im einheitlichen Stil schreiben, dann fallen Reviews leichter, da der Code nicht erst an die gemeinsamen Regeln angepasst werden muss.<\/li>\n\n\n\n<li>Schwer lesbarer und damit schwer nachvollziehbarer Code kann zu Fehlern und Sicherheitsrisiken f\u00fchren.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Welche Code-Standards gibt es?<\/h3>\n\n\n\n<p>Moderne IDEs k\u00f6nnen Code selbstst\u00e4ndig formatieren. Dazu k\u00f6nnen in die IDE integrierte Formatierungsregeln verwendet, angepasst, exportiert und importiert werden. Die in Eclipse und IntelliJ standardm\u00e4\u00dfig integrierten Code-Stile sind allerdings unterschiedlich. Eclipse hat die Stile \"Java Conventions\", \"Eclipse\" und \"Eclipse 2.1\"; IntelliJ bietet den \"Default\"-Stil an. <\/p>\n\n\n\n<p>IntelliJ kann von Eclipse exportierte Formate importieren, andersherum ist das nicht m\u00f6glich. Da IntelliJ mit einem importierten Eclipse-Format nicht 100 % denselben Code generiert wie Eclipse, gibt es au\u00dferdem das <a rel=\"noopener\" href=\"https:\/\/plugins.jetbrains.com\/plugin\/6546-adapter-for-eclipse-code-formatter\/\" target=\"_blank\">Eclipse Code Formatter<\/a>-Plugin, das den Code in IntelliJ auf die exakt gleiche Art und Weise formatiert wie Eclipse.<\/p>\n\n\n\n<p>Die \"Java Conventions\" aus Eclipse entsprechen den 1997 von Sun herausgegebenen und zuletzt 1999 \u00fcberarbeiteten <a rel=\"noopener\" href=\"https:\/\/www.oracle.com\/java\/technologies\/cc-java-programming-language.html\" target=\"_blank\">Java Code Conventions<\/a>. Entsprechend kennt dieser Stil keine neueren Sprachelemente wie bspw. Generics oder Lambdas. <\/p>\n\n\n\n<p>Ein moderner und verbreiteter IDE-unabh\u00e4ngiger Code-Stil ist der <a rel=\"noopener\" href=\"https:\/\/google.github.io\/styleguide\/javaguide.html\" target=\"_blank\">Google Java Style Guide<\/a>, welcher in vielen Projekten entweder direkt oder leicht abgewandelt verwendet wird. Der Google-Stil hat folgende Vorteile:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Es werden Konfigurationsfiles f\u00fcr Eclipse, IntelliJ und Checkstyle (dazu unten mehr) angeboten.<\/li>\n\n\n\n<li>Es gibt nicht nur Vorgaben f\u00fcr Java, sondern f\u00fcr zahlreiche andere verbreitete Sprachen, wie HTML, CSS und JavaScript. So kann in einem Projekt, in dem verschiedene Sprachen zum Einsatz kommen, relativ einfach ein einheitlicher Stil verwendet werden.<\/li>\n<\/ul>\n\n\n\n<p>Um die Unterschiede zu demonstrieren, werde ich das folgende (sinnlose und absichtlich unsauber formatierte) Codest\u00fcck in allen zuvor genannten Code-Stilen formatieren.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_unformatted.png\"><img decoding=\"async\" width=\"420\" height=\"630\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_unformatted.png\" alt=\"Unformatierter Code\" class=\"wp-image-3158\" style=\"width:315px;height:473px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_unformatted.png 420w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_unformatted-224x336.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_unformatted-336x504.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_unformatted-400x600.png 400w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><figcaption class=\"wp-element-caption\">Unformatierter Code<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Die Ergebnisse seht ihr in der folgenden Bilderstrecke (zum Vergr\u00f6\u00dfern anklicken). Da beim Google Java Style standardm\u00e4\u00dfig mit zwei Leerzeichen einger\u00fcckt wird, habe ich noch eine zus\u00e4tzlich Variante mit vier Leerzeichen eingef\u00fcgt.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_java_conventions.png\"><img decoding=\"async\" width=\"420\" height=\"735\" data-id=\"3168\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_java_conventions.png\" alt=\"Eclipse's &quot;Java Conventions&quot; formatter\" class=\"wp-image-3168\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_java_conventions.png 420w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_java_conventions-224x392.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_java_conventions-336x588.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_java_conventions-400x700.png 400w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><figcaption class=\"wp-element-caption\">Eclipse's \"Java Conventions\" formatter<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse.png\"><img decoding=\"async\" width=\"420\" height=\"735\" data-id=\"3163\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse.png\" alt=\"Eclipse's &quot;Eclipse&quot; formatter\" class=\"wp-image-3163\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse.png 420w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse-224x392.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse-336x588.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse-400x700.png 400w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><figcaption class=\"wp-element-caption\">Eclipse's \"Eclipse\" formatter<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse_2.1.png\"><img decoding=\"async\" width=\"420\" height=\"693\" data-id=\"3164\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse_2.1.png\" alt=\"Eclipse's &quot;Eclipse 2.1&quot; formatter\" class=\"wp-image-3164\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse_2.1.png 420w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse_2.1-224x370.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse_2.1-336x554.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_eclipse_2.1-400x660.png 400w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><figcaption class=\"wp-element-caption\">Eclipse's \"Eclipse 2.1\" formatter<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_intellij.png\"><img decoding=\"async\" width=\"420\" height=\"756\" data-id=\"3167\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_intellij.png\" alt=\"IntelliJ's &quot;Default&quot; formatter\" class=\"wp-image-3167\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_intellij.png 420w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_intellij-224x403.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_intellij-336x605.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_intellij-400x720.png 400w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><figcaption class=\"wp-element-caption\">IntelliJ's \"Default\" formatter<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google.png\"><img decoding=\"async\" width=\"420\" height=\"798\" data-id=\"3165\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google.png\" alt=\"Google Java Style\" class=\"wp-image-3165\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google.png 420w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google-224x426.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google-336x638.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google-400x760.png 400w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><figcaption class=\"wp-element-caption\">Google Java Style<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google_4spaces.png\"><img decoding=\"async\" width=\"420\" height=\"798\" data-id=\"3166\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google_4spaces.png\" alt=\"Google Java Style with 4-space indentation\" class=\"wp-image-3166\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google_4spaces.png 420w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google_4spaces-224x426.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google_4spaces-336x638.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/code_style_google_4spaces-400x760.png 400w\" sizes=\"(max-width: 420px) 100vw, 420px\" \/><\/a><figcaption class=\"wp-element-caption\">Google Java Style with 4-space indentation<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p>Wie ihr seht, sind alle Styles recht \u00e4hnlich. In allen wird eine leicht abgewandelte Variante des sogenannte \"<a rel=\"noopener\" href=\"https:\/\/de.wikipedia.org\/wiki\/Einr%C3%BCckungsstil#1TBS_\/_K&amp;R_\/_Kernel_\/_Linux_\/_UNIX_\/_Stroustrup_\/_Java_\/_Sun\" target=\"_blank\">One True Brace Style<\/a>\" (1TBS) oder auch \"Kernighan &amp; Ritchie Style\" (K&amp;R) verwendet: Die \u00f6ffnende geschweifte Klammer befindet sich in derselben Zeile wie die zugeh\u00f6rige Klassen- bzw. Methodendefinition oder des entsprechenden Control-Statements.<\/p>\n\n\n\n<p>Unterschiede sieht man in Details, wie bspw. <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ob in einer Array-Definition zwischen den eckigen und den geschweiften Klammern oder auch innerhalb der geschweiften Klamern Leerzeichen stehen, <\/li>\n\n\n\n<li>ob geschweifte Klammern um einzelne Statements erforderlich oder optional sind,<\/li>\n\n\n\n<li>ob einzelne Statements in derselben Zeile direkt hinter dem Control Statement stehen d\u00fcrfen,<\/li>\n\n\n\n<li>ob Leerzeilen entfernt oder eingef\u00fcgt werden.<\/li>\n<\/ul>\n\n\n\n<p>Gerade diese Details sind es, die beim Review st\u00f6ren, insbesondere wenn man Code-\u00c4nderungen hervorhebt und dann die beabsichtigten \u00c4nderungen aus dem Grundrauschen der vielen kleinen Formatierungs\u00e4nderungen herausfiltern muss.<\/p>\n\n\n\n<p>Wenn ihr einen eigenen Stil entwickelt, sollte dieser von den bekannten Stilen nur geringf\u00fcgig abweichen, sodass Entwickler sich nicht lange ungew\u00f6hnen m\u00fcssen, sondern den Stil m\u00f6glichst intuitiv verstehen k\u00f6nnen. Mein bevorzugter Stil entspricht im Prinzip Google Style (also insbesondere das erforderliche Setzen von geschweiften Klammern um einzelne Statements) mit dem einzigen Unterschied, dass ich um 4 Leerzeichen einr\u00fccke statt um 2, so wie ich es aus den urspr\u00fcnglichen Java Code Conventions gew\u00f6hnt bin.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wie kann statische Code-Analyse einheitlichen Code-Standard sicherstellen?<\/h3>\n\n\n\n<p>Moderne IDEs k\u00f6nnen den Code zwar formattieren, allerdings gibt es folgende zwei Einschr\u00e4nkungen:<\/p>\n\n\n\n<p>1. Sie k\u00f6nnen nicht alle Coding-Vorgaben sicherstellen, bspw. nicht die folgenden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>maximale Methoden- und Klassenl\u00e4nge,<\/li>\n\n\n\n<li>maximale Anzahl \"Non Commenting Source Statements\" in einer Methode,<\/li>\n\n\n\n<li>maximale Anzahl von Parametern einer Methode,<\/li>\n\n\n\n<li>maximale Verschachtelungstiefe von Schleifen und Control-Statements.<\/li>\n<\/ul>\n\n\n\n<p>2. Sie k\u00f6nnen nicht sicherstellen, dass alle Entwickler die Formatter aktiviert und korrekt konfiguriert haben.<\/p>\n\n\n\n<p>Hier springen statische Code Analyse-Tools der Kategorie \"\u00dcberpr\u00fcfung des Code-Standards\" ein, die eben genau diese L\u00fccke schlie\u00dfen. Sind die entsprechenden Tools einmal konfiguriert und in die Build-Pipeline integriert, dann ist sichergestellt, dass \u00fcber das gesamte Projekt und von allen Teammitgliedern der gleiche Code-Stil verwendet wird. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tools zur \u00dcberpr\u00fcfung des Code-Standards<\/h3>\n\n\n\n<p>Der bekannteste Open-Source-Vertreter ist <a rel=\"noopener\" href=\"https:\/\/checkstyle.sourceforge.io\/\" target=\"_blank\">Checkstyle<\/a>. Checkstyle kann ziemlich flexibel konfiguriert und auf alle oben genannten Code-Stile angepasst werden. F\u00fcr den Google Java Style ist eine Checkstyle-Konfigurationsdatei zum Download verf\u00fcgbar. Ebenso kann Checkstyle in den Build-Prozess integriert werden, so dass dieser Warnungen ausgibt oder fehlschl\u00e4gt, wenn gegen die Regeln versto\u00dfen wurde. Auf Checkstyle werde ich im dritten Teil des Artikels detaillierter eingehen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Berechnung von Softwaremetriken<\/h2>\n\n\n\n<p>Softwaremetriken sind Funktionen, die bestimmte Qualit\u00e4tsmerkmale einer Software (wie z. B. Wartbarkeit, Erweiterbarkeit oder Verst\u00e4ndlichkeit) in einem objektiven und vergleichbaren numerischen Wert (z. B. \"maintainability index\", \"zyklomatische Komplexit\u00e4t\") darstellen. Softwaremetriken k\u00f6nnen Entwickler und Teams dabei helfen Qualit\u00e4tsziele zu erreichen. Dazu werden entsprechende Tools in den Build-Prozess integriert, um die Softwaremetriken zu berechnen und die Entwickler bei Abweichungen von zuvor festgelegten Sollwerten zu alarmieren.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Welche Softwaremetriken gibt es?<\/h3>\n\n\n\n<p>Einige der bekanntesten Metriken sind die folgenden:<\/p>\n\n\n\n<p>Kompexit\u00e4tsmetriken:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kopplung (coupling): das Ma\u00df der Abh\u00e4ngigkeiten zwischen den Modulen eines Systems \u2013 eine niedrige Kopplung f\u00fchrt zu besserer Verst\u00e4ndlichkeit und Wartbarkeit; <\/li>\n\n\n\n<li><span style=\"font-size: 1rem;\">Koh\u00e4sion (cohesion): das Ma\u00df der Abh\u00e4ngigkeiten innerhalb eines Softwaremoduls <\/span>\u2013 <span style=\"font-size: 1rem;\">eine hohe Koh\u00e4sion f\u00fchrt zu besserer Verst\u00e4ndlichkeit und Wartbarkeit;<\/span><\/li>\n\n\n\n<li>Average Component Dependency: die durchschnittliche Anzahl von Abh\u00e4ngigkeiten der Komponenten in einem Softwaresystem;<\/li>\n\n\n\n<li><span style=\"font-size: 1rem;\">Zirkul\u00e4ren Abh\u00e4ngigkeiten (circular dependencies): diese sind gleichzustellen mit einer hohen Kopplung der involvierten Module \u2013 keines kann alleinstehend wiederverwendet werden \u2013 und keines kann ohne die anderen verstanden werden;<\/span><\/li>\n\n\n\n<li>Zyklomatische Komplexit\u00e4t (cyclomatic complexity): die Anzahl unterschiedlicher Pfade durch ein Softwaremodul \u2013 je h\u00f6her die zyklomatische Komplexit\u00e4t, desto schwieriger ist das Softwaremodul zu verstehen;<\/li>\n\n\n\n<li>Maintainability Index: ein Wert, der sich aus der Kombination bestimmter anderer Metriken ergibt.<\/li>\n<\/ul>\n\n\n\n<p>Metriken zur Testabdeckung (code coverage \/ test coverage):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Line coverage: dieser Wert gibt an, wie viele Codezeilen im Verh\u00e4ltnis zur Gesamtanzahl der Codezeilen durch automatische Tests abgedeckt sind;<\/li>\n\n\n\n<li>Branch coverage: das Verh\u00e4ltnis der durch Tests abgedeckten Programmablaufpfade zu den gesamt m\u00f6glichen Ablaufpfaden.<\/li>\n<\/ul>\n\n\n\n<p>Folgende Grafik zeigt die zirkul\u00e4ren Abh\u00e4ngigkeiten eines Projekts, an dem ich gearbeitet habe:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><a href=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies.png\"><img decoding=\"async\" width=\"800\" height=\"510\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-800x510.png\" alt=\"Zirkul\u00e4re Abh\u00e4ngigkeiten zwischen 63 Java-Packages\" class=\"wp-image-3229\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-800x510.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-224x143.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-336x214.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-504x321.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-672x429.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-400x255.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-600x383.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies-944x602.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/Circular_Package_Dependencies.png 1179w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><figcaption class=\"wp-element-caption\">Zirkul\u00e4re Abh\u00e4ngigkeiten zwischen 63 Java-Packages<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Bis wir die zirkul\u00e4ren Abh\u00e4ngigkeiten aufgel\u00f6st hatten (durch Neuzuordnung von Klassen zu Packages sowie durch Anwendung des <a rel=\"noopener\" href=\"https:\/\/de.wikipedia.org\/wiki\/Dependency-Inversion-Prinzip\" target=\"_blank\">Dependency Inversion Principle<\/a>), war es unm\u00f6glich Teile des Codes in wiederverwendbare Module auszulagern. Auch war es insbesondere f\u00fcr neue Entwickler im Team sehr schwer sich in Code-Teile einzuarbeiten, da dies letztendlich ein zumindest grobes Verst\u00e4ndnis aller 63 Packages erforderte.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tools zur Berechnung von Softwaremetriken<\/h3>\n\n\n\n<p>Die bekanntesten Open-Source-Tools dieser Kategorie sind <a rel=\"noopener\" href=\"https:\/\/www.eclemma.org\/jacoco\/\" target=\"_blank\">JaCoCo<\/a> und <a rel=\"noopener\" href=\"https:\/\/cobertura.github.io\/cobertura\/\" target=\"_blank\">Cobertura<\/a> zur Messung der Testabdeckung, <a rel=\"noopener\" href=\"https:\/\/www.hello2morrow.com\/products\/sonargraph\/explorer\" target=\"_blank\">Sonargraph Explorer<\/a> f\u00fcr die Berechnung und Darstellung von (zyklischen) Abh\u00e4ngigkeiten, sowie <a rel=\"noopener\" href=\"https:\/\/www.sonarsource.com\/products\/sonarqube\/\" target=\"_blank\">SonarQube<\/a> f\u00fcr die Berechnung von Metriken zur Komplexit\u00e4t, Wartbarkeit, Zuverl\u00e4ssigkeit, Sicherheit und Testabdeckung.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Erkennung von Fehlern im Code<\/h2>\n\n\n\n<p>Tools dieser Kategorie versuchen potentielle Fehler im Code zu finden, in dem sie h\u00e4ufig vorkommende Fehlermuster erkennen. Beispiele daf\u00fcr sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>sichere\/potentielle <code>NullPointerException<\/code>s,<\/li>\n\n\n\n<li><span style=\"font-size: 1rem;\">Vergleich mit <\/span><code>equals()<\/code><span style=\"font-size: 1rem;\"> auf Objekten verschiedener Klassen<\/span>,<\/li>\n\n\n\n<li>Klassen, die <code>equals()<\/code> definieren, aber nicht <code>hashCode()<\/code> \u2013 bzw. vice versa,<\/li>\n\n\n\n<li>String-Vergleiche mit <code>==<\/code> oder <code>!=<\/code> (so etwas ist entweder ein Fehler oder \u2013 wenn beabsichtigt \u2013 f\u00fcr den n\u00e4chsten Entwickler verwirrend und somit fehleranf\u00e4llig),<\/li>\n\n\n\n<li><code>switch<\/code>-Statements ohne <code>default<\/code>-Option,<\/li>\n\n\n\n<li><code>switch<\/code>-Statements mit \"fall throughs\" (diese sind verwirrend, da der Leser oft nicht wei\u00df, ob sie beabsichtigt sind),<\/li>\n\n\n\n<li>unbenutze Konstruktor- oder Methodenparameter,<\/li>\n\n\n\n<li>unbenutzte lokale Variablen,<\/li>\n\n\n\n<li>unbenutzte private Felder und Methoden,<\/li>\n\n\n\n<li>Resourcen, die nicht (in jedem Fall) geschlossen werden,<\/li>\n\n\n\n<li><span style=\"font-size: 1rem;\">Objekte, die Referenzen auf ver\u00e4nderliche interne Objekte, wie bspw. Listen nach au\u00dfen sichtbar machen (anstatt Kopien oder Read-Only-Proxys)<\/span>,<\/li>\n\n\n\n<li>fehlende <code>assert<\/code>-Statements in Unit-Tests.<\/li>\n<\/ul>\n\n\n\n<p>Statische Code-Analyse-Tools zur Erkennung von Fehlern sind bspw. der Java-Compiler selbst (mit entsprechenden Parametern), die Open Source Tools <a href=\"https:\/\/pmd.github.io\/\" target=\"_blank\" rel=\"noopener\">PMD<\/a>, <a href=\"https:\/\/findbugs.sourceforge.net\/\" target=\"_blank\" rel=\"noopener\">FindBugs<\/a> bzw. dessen Nachfolger <a href=\"https:\/\/spotbugs.github.io\" target=\"_blank\" rel=\"noopener\">SpotBugs<\/a>, und <a href=\"https:\/\/www.sonarsource.com\/products\/sonarqube\/\" target=\"_blank\" rel=\"noreferrer noopener\">SonarQube<\/a>, welche ich im dritten Teil der Artikelserie detailliert vorstellen werde.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Erkennung von Sicherheitsl\u00fccken<\/h2>\n\n\n\n<p>Letztendlich werden Sicherheitsl\u00fccken in der Software durch Fehler im Code verursacht. In Abgrenzung zur vorangegangenen Kategorie handelt es sich hierbei jedoch um Fehler, die deutlich schwieriger zu erkennen sind, da hierf\u00fcr aufw\u00e4ndige Datenfluss-Analysen durchgef\u00fchrt werden m\u00fcssen: Es muss gepr\u00fcft werden, wie Eingabedaten durch das System und ggf. auch durch externe Libraries flie\u00dfen und verarbeitet werden, sowohl \u00fcber regul\u00e4re als auch au\u00dferordentliche Ausf\u00fchrungspfade. Beispiele f\u00fcr Sicherheitsl\u00fccken sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Command und SQL Injection: fehlende\/unzureichende Verifizierung von Eingabewerten kann dazu f\u00fchren, dass z. B. User-Eingaben in Formularen durch die Software als (SQL-)Kommandos interpretiert werden k\u00f6nnen (z. B. \"<code>; delete * from User;<\/code>\" \u2013 wird dies unver\u00e4ndert als Teil einer Query an die Datenbank geschickt, wird m\u00f6glicherweise die komplette User-Tabelle geleert);<\/li>\n\n\n\n<li>Fehler in der Zugriffskontrolle, so dass unberechtigte User Funktionen ausf\u00fchren k\u00f6nnen, f\u00fcr die sie keine Berechtigung haben (z. B. private Daten anderer User auslesen);<\/li>\n\n\n\n<li>Cross-Site-Scripting: das Einschleusen von sch\u00e4dlichem ausf\u00fchrbaren Code z. B. \u00fcber Request-Parameter in einer URL;<\/li>\n\n\n\n<li>Cross-Site-Request-Forgery: hierbei wird einem eingeloggten User eines Systems ein Link untergeschoben, \u00fcber den dieser unbewusst eine f\u00fcr ihn sch\u00e4dliche Aktion ausf\u00fchrt (z. B. k\u00f6nnte er dadurch sein Passwort auf ein durch den Angreifer festgelegtes Passwort \u00e4ndern, woraufhin dieser sich in den User-Account einloggen k\u00f6nnte).<\/li>\n<\/ul>\n\n\n\n<p>Wichtige Begriffe im Zusamenhang mit Softwaresicherheit sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a rel=\"noopener\" href=\"https:\/\/cwe.mitre.org\/\" target=\"_blank\">CWE \u2013 Common Weakness Enumeration<\/a>: eine durch die Entwickler-Community erstellte Liste h\u00e4ufig auftretender Sicherheitsl\u00fccken, in der jeder Schwachstelle ein eindeutiger Bezeichner zugewiesen wird, wie bspw. CWE-77 f\u00fcr die oben erw\u00e4hnte \"Command Injection\" oder CWE-89 f\u00fcr \"SQL Injection\". Diese Liste ist nicht priorisiert. Sie dient sozusagen als gemeinsame Sprache: fast alle Softwaresicherheitstools geben bei erkannten Schwachstellen den entsprechenden CWE-Identifikator mit an.<\/li>\n\n\n\n<li><a rel=\"noopener\" href=\"https:\/\/owasp.org\/\" target=\"_blank\">OWASP \u2013 Open Web Application Security Project<\/a>: eine Non-Profit-Organisation mit dem Ziel die Sicherheit von Software zu erh\u00f6hen. Das bekannteste Projekt ist die \u201e<a href=\"https:\/\/owasp.org\/www-project-top-ten\/\" target=\"_blank\" rel=\"noopener\" aria-label=\" (opens in a new tab)\">OWASP Top 10<\/a>\u201c-Liste, die die aktuell zehn kritischsten Sicherheitsrisiken von Webanwendungen (einschlie\u00dflich ihrer CWE-Klassifikation) auflistet. Die Liste wurde zuletzt 2017 aktualisiert.<\/li>\n\n\n\n<li><a rel=\"noopener\" href=\"https:\/\/cwe.mitre.org\/top25\/\" target=\"_blank\">CWE\/SANS Top 25 Most Dangerous Software Errors<\/a>: eine alternative Liste der 25 kritischsten Sicherheitsrisiken \u2013 allerdings seit 2011 nicht aktualisiert.<\/li>\n<\/ul>\n\n\n\n<p>Diese Listen sind priorisiert und k\u00f6nnen somit verwendet werden, um die Behebung von Sicherheitsl\u00fccken zu priorisieren (s. <a href=\"#Rollout-Strategie\">Rollout-Strategie<\/a>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">OWASP-Benchmark<\/h3>\n\n\n\n<p>Ein weiteres OWASP-Projekt ist der <a href=\"https:\/\/owasp.org\/www-project-benchmark\/\" target=\"_blank\" rel=\"noopener\">OWASP-Benchmark<\/a>. Diese kostenlose, quelloffene Test-Suite pr\u00fcft, wie gut ein Softwaresicherheitstool bestimmte Schwachstellen aufsp\u00fcrt, d. h. wie viele tats\u00e4chliche Fehler es findet und \u2013 dem gegen\u00fcbergestellt \u2013 wie viele false positives es meldet. Der OWASP-Benchmark hilft die verf\u00fcgbaren Sicherheitstools untereinander zu vergleichen und entsprechend den Anforderungen an die Softwaresicherheit zu beurteilen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tools f\u00fcr die Erkennung von Sicherheitsl\u00fccken<\/h3>\n\n\n\n<p>Im Open-Source-Bereich sind mir hier <a rel=\"noopener\" href=\"https:\/\/find-sec-bugs.github.io\/\" target=\"_blank\">Find Security Bugs<\/a>, ein FindBugs\/SpotBugs-Plugin, und das oben bereits erw\u00e4hnte <a rel=\"noopener\" href=\"https:\/\/www.sonarsource.com\/products\/sonarqube\/\" target=\"_blank\">SonarQube<\/a> bekannt. Beide werde ich im dritten Teil der Serie n\u00e4her vorstellen. F\u00fcr Anwendungen mit erh\u00f6hten Sicherheitsanforderungen sollte man hier ggf. auf Tools kommerzieller Anbieter zur\u00fcckgreifen, welche allerdings au\u00dferhalb des Rahmens dieser Artikelserie liegen.<\/p>\n\n\n\n<p>Einen sehr in die Tiefe gehenden Artikel zu diesem Thema findet ihr im <a rel=\"noopener\" href=\"https:\/\/entwickler.de\/magazine-ebooks\/java-magazin\/java-magazin-72018\" target=\"_blank\">Java Magazin 7\/2018<\/a> ab S. 16. unter dem Titel \"Neue Wege analysieren \u2013 Softwaresicherheit und Datenschutz mithilfe statischer Codeanalyse\".<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Querschnittsaspekt: Fortschritts\u00fcberwachung<\/h2>\n\n\n\n<p>Die Tools aller zuvor genannten Kategorien liefern bei jedem Durchlauf numerische Werte, anhand derer quantitative Aussagen \u00fcber die Qualit\u00e4t der Software gemacht werden k\u00f6nnen, wie bspw.:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Anzahl Code-Stil-Warnungen bzw. -Fehler,<\/li>\n\n\n\n<li><span style=\"font-size: 1rem;\">Anzahl Tests und Anzahl bzw. Prozentsatz der Code-Zeilen, die durch Tests abgedeckt sind<\/span>,<\/li>\n\n\n\n<li>Anzahl duplizierter Code-Bl\u00f6cke bestimmter L\u00e4ngen,<\/li>\n\n\n\n<li>Anzahl zirkul\u00e4rer Abh\u00e4ngigkeiten zwischen Klassen bzw. Packages,<\/li>\n\n\n\n<li>Zyklomatische Komplexit\u00e4t,<\/li>\n\n\n\n<li>Anzahl potentieller Fehler bestimmter Kategorien.<\/li>\n<\/ul>\n\n\n\n<p>Es gibt Tools, die diese Metriken im zeitlichen Verlauf speichern und darstellen k\u00f6nnen. Somit kann das Entwicklungsteam nachverfolgen, wie sich die Code-Qualit\u00e4t im Laufe der Zeit ver\u00e4ndert. Dies erm\u00f6glicht es auch Ziele zu setzen, wie z. B. die Test-Coverage in Zeitraum x um y Prozentpunkte zu erh\u00f6hen, oder die zyklomatische Komplexit\u00e4t in Zeitraum x um Betrag y zu reduzieren.<\/p>\n\n\n\n<p>Das wohl bekannteste Open-Source-Tool dieser Art ist die Community Edition von <a rel=\"noopener\" href=\"https:\/\/www.sonarsource.com\/products\/sonarqube\/\" target=\"_blank\">SonarQube<\/a>, welches nicht nur \u2013 wie oben erw\u00e4hnt \u2013 Code-Metriken berechnen kann, sondern diese auch im zeitlichen Verlauf speichert und visualisiert. \u00dcber Plugins kann SonarQube die Metriken anderer statischer Code Analyse-Tools importieren und auch deren Historien speichern.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rollout-Strategie<\/h2>\n\n\n\n<p>Optimalerweise setzt man Statische Code-Analyse-Tools bereits zu Beginn des Projekts ein, um teure Refactorings zu einem sp\u00e4teren Zeitpunkt zu vermeiden. Selbstverst\u00e4ndlich kann man die Tools auch in bestehende Projekte einf\u00fchren. Um die Entwickler in der IDE und durch Build-Reports nicht mit Tausenden von Warnmeldungen zu \u00fcberfluten (deren Behebung dann aufgrund der un\u00fcberschaubaren Anzahl gerne wieder und wieder verschoben wird) sollte man eine Rollout-Strategie erarbeiten.<\/p>\n\n\n\n<p>Bei AndroidPIT haben wir das wir folgt gemacht: Wir haben zun\u00e4chst alle Tools mit den Default-Einstellungen installiert und uns einen groben \u00dcberblick \u00fcber die Meldungen verschafft. Dann haben wir im Team entschieden, welche wir f\u00fcr sinnvoll halten und welche nicht. Die f\u00fcr uns nicht sinnvollen haben wir abgeschaltet. Gab es zu bestimmten Fehlerarten nur vereinzelte Warnungen, haben wir diese direkt behoben, sofern dies kein allzu hoher Aufwand war. Was \u00fcbrig blieb (immer noch mehrere Tausend Meldungen) haben wir priorisiert. Dabei haben wir allen sicherheitsrelevanten Meldungen als erstes betrachtet und diese entsprechend der OWASP Top 10 priorisiert. Wie wir nicht sicherheitsrelevante Meldungen priorisieren, haben wir im Team entschieden.<\/p>\n\n\n\n<p>Dann haben wir alle Meldungen bis auf die h\u00f6chst priorisierte Kategorie deaktiviert und nach und nach die verbleibenden Warnungen analysiert und den Code entsprechend verbessert. Teilweise haben wir dies im Rahmen von Tickets gemacht (insbesondere bei den Sicherheitsrisiken), teilweise haben Team-Mitglieder, wenn sie eine Abwechslung von ihrem regul\u00e4ren Task brauchten, Warnungen abgearbeitet. Sobald alle Warnungen beseitigt waren, haben wir die n\u00e4chstwichtigte Kategorie aktiviert und wiederum abgearbeitet. Zwischendurch kamen durch Updates der Tools neue Warnungen hinzu, die wir dann wiederum einpriorisiert und vor\u00fcbergehend deaktiviert haben. Jenkins haben wir so konfiguriert, dass unsere Projekte trotz bestehender Warnungen stets stabil waren und nur dann als unstabil gekennzeichnet wurden, wenn w\u00e4hrend der Entwicklung neue Probleme eingef\u00fcgt wurden.<\/p>\n\n\n\n<p>Bis wir alle Warnungen wieder aktiviert und anschlie\u00dfend beseitigt hatten, verging etwa ein Jahr. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Zusammenfassung und Ausblick<\/h2>\n\n\n\n<p>Dieser Artikel hat gezeigt, wie die im ersten Teil aufgef\u00fchrten Herausforderungen bei der Softwareentwicklung durch statische Code-Analyse-Tools gel\u00f6st werden k\u00f6nnen. Im dritten Teil werde ich die folgenden, alle zuvor genannten, Tools aus dem Java-Umfeld detaillierter vorstellen (hier alphabetisch sortiert):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Checkstyle<\/li>\n\n\n\n<li>Cobertura<\/li>\n\n\n\n<li>FindBugs \/ SpotBugs<\/li>\n\n\n\n<li>Find Security Bugs<\/li>\n\n\n\n<li>JaCoCo<\/li>\n\n\n\n<li>PMD<\/li>\n\n\n\n<li>Sonargraph Explorer<\/li>\n\n\n\n<li>SonarLint<\/li>\n\n\n\n<li>SonarQube<\/li>\n<\/ul>\n\n\n\n<p>Bis dahin, happy Coding!<\/p>\n\n\n\n<p>Hat dir der Artikel gefallen und kennst Du jemanden, der sich ebenfalls f\u00fcr das Thema interessiert? Dann freue ich mich, wenn Du den Artikel \u00fcber einen der folgenden Buttons teilst.<\/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>In diesem Artikel erf\u00e4hrst du, wie du statische Code-Analyse-Tools einsetzen kannst, um einen konsistenten Codestil zu gew\u00e4hrleisten und sauberen, fehlerfreien, wartbaren und sicheren Code zu schreiben.<\/p>\n","protected":false},"author":1,"featured_media":19194,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"So kannst Du mit Statischer Code-Analyse einen einheitlichen Code-Stil sicherstellen und sauberen, fehlerfreien, wartbaren Code schreiben.","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"none","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":301,"_seopress_analysis_target_kw":"statische code-analyse","_seopress_news_disabled":"","_seopress_video_disabled":"","_seopress_video":[{"url":"","title":"","desc":"","thumbnail":"","duration":"","rating":"","view_count":"","tag":"","cat":""}],"_seopress_pro_schemas_manual":[{"_seopress_pro_rich_snippets_type":"none"}],"_seopress_pro_rich_snippets_disable_all":"","_seopress_pro_rich_snippets_disable":[],"_seopress_pro_schemas":[],"_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":19870,"_post_count":0,"footnotes":""},"categories":[64],"tags":[120],"class_list":["post-3107","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-produktivitaet"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",1200,675,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",300,169,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",768,432,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",1024,576,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-224x126.jpg",224,126,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-336x189.jpg",336,189,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-504x284.jpg",504,284,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-672x378.jpg",672,378,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-400x225.jpg",400,225,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-600x338.jpg",600,338,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-800x450.jpg",800,450,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse-944x531.jpg",944,531,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",1200,675,false],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",871,490,false],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",1200,675,false],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",1200,675,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2019\/08\/besseren-code-schreiben-statische-code-analyse.jpg",1200,675,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"In diesem Artikel erf\u00e4hrst du, wie du statische Code-Analyse-Tools einsetzen kannst, um einen konsistenten Codestil zu gew\u00e4hrleisten und sauberen, fehlerfreien, wartbaren und sicheren Code zu schreiben.","public_identification_id":"49fb26da0ecc47fb84704e51d2567401","private_identification_id":"5c37d4323ba446bdbf6497feac55cadb","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/3107","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=3107"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/3107\/revisions"}],"predecessor-version":[{"id":54283,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/3107\/revisions\/54283"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/19194"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=3107"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=3107"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=3107"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}