9 zu vermeidende Fehler bei der Programmierung in Java
Rafal Sawicki
Java-Entwickler
Welche Fehler sollten bei der Programmierung in Java vermieden werden? Im folgenden Beitrag beantworten wir diese Frage.
Java ist eine beliebte Sprache, die sich in der Welt der Software-Entwicklung. Es ist eine starke und vielseitige Programmiersprache. Rund 3 Milliarden Geräte weltweit laufen mit Java und deshalb wurden bei der Verwendung mindestens 3 Milliarden Fehler gemacht. In diesem Artikel wollen wir uns darauf konzentrieren, wie wir keine weiteren Fehler mehr machen können.
1. Ausnahme bei gleichzeitiger Änderung
Dies ist bei weitem der häufigste Fehler, der mir begegnet ist. In den ersten Tagen meiner Karriere habe ich ihn auch oft gemacht. Dieser Fehler tritt auf, wenn man versucht, die Sammlung zu ändern, während man sie durchläuft. Die ConcurrentModificationException kann auch ausgelöst werden, wenn Sie mit mehreren Threads arbeiten, aber konzentrieren wir uns zunächst auf ein Basisszenario.
Angenommen, Sie haben eine Sammlung von Nutzern, von denen einige erwachsen sind und einige nicht. Ihre Aufgabe ist es, die Kinder herauszufiltern.
for (Benutzer : Benutzer) {
if (!benutzer.istErwachsen()) {
users.remove(user);
}
}
Die Ausführung der oben erwähnten Code endet damit, dass man ConcurrentModificationException. Was haben wir falsch gemacht? Bevor wir unsere Iteration abgeschlossen haben, haben wir versucht, einige Elemente zu entfernen. Das ist der Grund für die Ausnahme.
Wie kann ich sie vermeiden?
In diesem Fall gibt es mehrere Ansätze, die helfen können. Zuallererst sollten Sie die Vorteile nutzen Java Die Güte der 8 - Stream.
List adults = users.stream()
.filter(Benutzer::istErwachsen)
.toList();
Mit einer Prädikat Filter haben wir die Umkehrung der vorherigen Bedingung durchgeführt - jetzt bestimmen wir die Elemente, die einbezogen werden sollen. Der Vorteil eines solchen Ansatzes ist, dass es einfach ist, andere Funktionen nach dem Entfernen zu verketten, z. B. Karte. Aber um Himmels willen, versuchen Sie bitte nicht, so etwas wie unten zu tun:
Es könnte auch in der ConcurrentModificationException weil Sie die Stream-Quelle ändern. Es kann auch zu weiteren Ausnahmen kommen, die nicht leicht zu beheben sind.
Zu lösen ConcurrentModificationException in einem Single-Thread-Szenario. Sie könnten auch dazu übergehen, direkt mit Iterator und seine entfernen() Methode, oder Sie könnten einfach keine Elemente während der Iteration entfernen. Meine Empfehlung ist jedoch, die Methode Ströme - wir schreiben das Jahr 2022.
2. Speichern von Passwörtern als Strings
Da ich mich immer mehr mit dem Thema Cybersec beschäftige, wäre ich mir selbst nicht treu, wenn ich nicht mindestens eine davon erwähnen würde Java-Fehler die zu einem Sicherheitsproblem führen können. Die Speicherung der von den Benutzern erhaltenen Passwörter in einem Zeichenfolge Objekt ist genau das, wovor Sie Angst haben sollten.
Das Problem (oder vielleicht der Vorteil) von Zeichenfolge ist, dass er unveränderlich ist. In der Welt der Cybersecurity stellt dies eine potenzielle Bedrohung dar, da man den Wert einer einmal erstellten Datei nicht löschen kann. Zeichenfolge Objekt. Ein Angreifer, der sich Zugang zum Speicher Ihres Computers verschafft, kann dort Klartextkennwörter finden.
Zweitens: Zeichenketten in Java werden von der JVM interniert und im PermGen-Bereich oder im Heap-Bereich gespeichert. Wenn Sie eine Zeichenfolge Objekts wird es zwischengespeichert und erst entfernt, wenn der Garbage Collector seine Arbeit aufnimmt. Sie können nicht sicher sein, wann Ihr Kennwort aus dem String-Pool gelöscht wird, da der Garbage Collector auf nicht-deterministische Weise arbeitet.
Wie kann man sie vermeiden?
Die empfohlene Vorgehensweise ist die Verwendung von char[] oder, noch besser, die Bibliothek, die das Speichern von Passwörtern als char[]z.B.Passwort4j. Die char[] Array ist veränderbar und kann nach seiner Initialisierung geändert werden. Nach der Verarbeitung eines Passworts können Sie einfach das char[] Passwort-Array, indem sie zufällige Zeichen hineinschreiben. Falls die Angreifer Zugriff auf den Speicher Ihres Computers erhalten, sehen sie nur einige Zufallswerte, die nichts mit den Kennwörtern der Benutzer zu tun haben.
3. (Un-)Behandlung von Ausnahmen
Neulinge und auch fortgeschrittene Programmierer wissen nicht, wie man Ausnahmen richtig behandelt. Ihre größte Sünde ist es, sie einfach zu ignorieren. DAS IST NIEMALS EIN GUTER ANSATZ.
Leider können wir Ihnen keine Patentlösung anbieten, die für jede Situation geeignet ist. Ausnahmes"-Szenario, das Ihnen begegnet. Sie müssen über jeden Fall einzeln nachdenken. Wir können Ihnen jedoch einige Tipps geben, wie Sie mit diesem Thema beginnen können.
Wie kann ich sie vermeiden?
Ignorieren Ausnahmes ist nie eine gute Praxis. Ausnahmes werden aus irgendeinem Grund eingefügt, daher sollten Sie sie nicht ignorieren.
try {...} catch(Exception e) { log(e); } ist selten der richtige Ansatz für Ausnahme Handhabung.
Werfen Ausnahmeeinen Fehlerdialog für den Benutzer anzeigen oder zumindest eine umfassende Meldung in das Protokoll aufnehmen.
Wenn Sie Ihre Ausnahmen unbehandelt gelassen haben (was Sie nicht tun sollten), erklären Sie sich wenigstens in einem Kommentar.
4. Null verwenden
Leider kommt es häufig vor, dass eine Java-Funktion in einigen Fällen eine null. Das Problem besteht darin, dass eine solche Funktion ihren Klienten dazu zwingt, das Ergebnis einer Nullprüfung zu unterziehen. Ohne dies würde die NullPointerException geworfen wird.
Die andere Sache ist die Übergabe einer null Wert. Wie kommen Sie überhaupt auf diese Idee? In einem solchen Fall muss die Funktion eine Null-Prüfung durchführen. Wenn Sie Bibliotheken von Drittanbietern verwenden, können Sie das Innere der Funktionen nicht ändern. Was dann?
Noch wichtiger ist, dass andere Entwickler, die Ihren Code lesen und sehen, dass Sie die null werden wahrscheinlich verwirrt sein, warum Sie eine so bizarre Art und Weise gewählt haben, Ihre Funktion zu implementieren.
Wie kann ich sie vermeiden?
Keine Rückgabe einer null Wert! Niemals! Für den Fall, dass Ihre Funktion eine Art von Sammlungkönnen Sie einfach ein leeres Sammlung. Wenn Sie mit einzelnen Objekten arbeiten, können Sie das Null-Objekt-Designmuster verwenden. Da Java 8, wird sie implementiert als Optional. Ansonsten ist die am wenigsten empfehlenswerte Vorgehensweise die Erhebung einer Ausnahme.
5. Schwere String-Verkettung
Hoffentlich machen Sie keinen Fehler, denn es ist die beliebteste (oder vielleicht die zweitbeliebteste nach FizzBuzz) Interviewfrage. Wie Sie inzwischen wissen sollten, ist eine Zeichenfolge Objekt ist unveränderlich in Java - einmal erstellt, kann sie nicht mehr geändert werden. Daher ist die Verkettung von Zeichenfolge Literale bedeutet eine Menge unnötiger Speicherzuweisung. Verkettung Zeichenfolge Objekte zu erstellen, muss jedes Mal eine temporäre StringBuilder Objekt und wandelt es wieder in eine Zeichenkette um. Daher ist diese Lösung absolut ungeeignet, wenn wir eine große Anzahl von Zeichen kombinieren wollen.
Wie kann ich sie vermeiden?
Um dieses Problem zu lösen, verwenden Sie StringBuilder. Es entsteht ein veränderbares Objekt, das leicht manipuliert werden kann. Natürlich können Sie jederzeit StringBuffer wenn Ihr Projekt in einem konkurrierenden Kontext verwendet wird.
6. Keine Nutzung bestehender Lösungen
Bei der Entwicklung von Software ist es ein Muss, die Grundlagen der Sprache, in der man schreibt, zu kennen, aber es reicht nicht aus. Viele algorithmische Probleme, auf die Sie bei der Implementierung einer neuen Funktion stoßen, wurden bereits von jemand anderem gelöst. Zu oft habe ich erlebt, dass jemand einen Sicherheitsalgorithmus von Grund auf neu implementiert hat. Ein solcher Ansatz ist fehleranfällig. Eine einzelne Person kann eine so komplexe Lösung nicht gründlich testen. Das kollektive Wissen der Team die aus mittelmäßig fortgeschrittenen Programmierern besteht, ist fast immer besser als die Größe eines einzelnen Wunderkinds Java-Entwickler. Sie brauchen das Rad nicht neu zu erfinden - Sie müssen lediglich die bestehende Lösung an Ihre Bedürfnisse anpassen.
Wie kann ich sie vermeiden?
Versuchen Sie, nach Bibliotheken zu suchen, die sich mit dem Problem befassen, an dem Sie gerade arbeiten. Versuchen Sie, ähnliche Lösungen zu finden. Viele der im Internet verfügbaren Bibliotheken sind kostenlos und wurden von erfahrenen Entwicklern und der gesamten Java-Gemeinschaft ausgefeilt und getestet. Scheuen Sie sich nicht, von ihnen Gebrauch zu machen.
7. Nicht genügend Zeit für das Schreiben von Tests finden
Es ist verlockend zu glauben, dass unser Code immer perfekt laufen wird. Keine Tests für den Code zu schreiben, ist die schlimmste Sünde der Java Softwareentwickler. Viele von uns bevorzugen manuelle und explorative Tests anstelle von Unit-Tests, was verrückt ist. Warum Zeit mit dem Schreiben von Tests verschwenden, wenn man sich darauf konzentrieren kann, den weltbesten Code für sein Projekt zu liefern, der DEFINITELY keine Bugs hat?<joke>. Die Realität ist brutal, und ohne das Schreiben von Tests können wir keinen hochwertigen Code liefern.
Wie kann ich sie vermeiden?
Sie sollten immer Tests für Ihren Code vorbereiten. Ich weiß, dass der TDD-Ansatz nicht so einfach zu pflegen ist, aber Sie sollten zumindest Tests erstellen, die alle Bedingungen abdecken, unter denen Ihr Code ausgeführt werden kann. Dazu gehört auch das Testen von Ausnahmesituationen. Die Unit-Tests sind notwendig. Sie müssen sie für jede Funktion Ihres Projekts bereitstellen, wenn Sie sicherstellen wollen, dass Ihr Code in der weiteren Entwicklung leicht zu refaktorisieren und zu erweitern ist.
Noch eine Sache. Halten Sie einen hohen Standard Ihres Testcodes aufrecht - es wird sich lohnen. Das ist Onkel Bobs Rat und ich stimme ihm voll und ganz zu.
Vergessen Sie auch nicht die anderen Arten von Tests. Integrationstests sind eine Sache, die Sie bei jedem Projekt berücksichtigen sollten.
8. Vergessen von Zugangsmodifikatoren
Privat und öffentlich, richtig? Wie könnten wir sie vergessen? Es gibt aber noch mehr. Als Sie mit dem Lernen begannen Javahaben Sie sicherlich über geschützte Zugriffsmodifikatoren gelernt. Sie können in einigen Fällen nützlich sein, daher lohnt es sich, über ihre Existenz Bescheid zu wissen.
Java-Entwickler scheinen oft zu vergessen, dass es einen Paketbereich gibt. Es ist leicht, sich nicht daran zu erinnern, ihn zu benutzen, da er implizit ist und keine Java Schlüsselwörter. Der Paketumfang ist wichtig. Mit ihm können Sie eine geschützte Methode testen. Auf geschützte Elemente kann über den Pfad der Testklasse zugegriffen werden, sofern das Paket dasselbe ist.
Wie kann ich sie vermeiden?
Denken Sie an den geschützten Modifikator und daran, dass Sie ihn mit dem Paketumfang testen können.
9. Verwendung von reinem JavaEE anstelle von Spring
Der nächste Schritt nach dem Lernen Java SE soll lernen, wie man läuft Java auf Servern, wie man eine Anwendung auf Unternehmensebene erstellt.
Neulinge tappen oft in die Falle, JavaEE zu lernen, da es eine große Anzahl von Tutorials dazu gibt. Selbst "Thinking in Java", das Java-ProgrammiererBibel', erwähnt JavaEE und sagt nichts über die anderen Optionen.
Wie kann ich sie vermeiden?
JavaEE ist ein Lied der Vergangenheit. Heutzutage ist Spring eine Selbstverständlichkeit und Java EE ist nur noch "nice to have". Jede moderne Unternehmensanwendung verwendet Spring, daher sollten Sie unbedingt in Erwägung ziehen, Spring zu lernen. es hier.