Schlagwort-Archive: String

Weil es so lustig war und ich neues Material gesammelt habe, denke ich, dass es an der Zeit ist, das Quellcode-Gruselkabinett mit einem zweiten Artikel fortzusetzen, womöglich zu beenden. Der (nicht näher definierte) Praktikant aus dem ersten Teil hat wieder zugeschlagen und hocheffizienten und extrem sinnvollen Java-Code produziert. Diese Glanzleistung moderner Softwareentwicklerkunst wollte ich denjenigen meiner Leser, die über Programmierkenntnisse (und Englischkenntnisse) verfügen, auf keinen Fall vorenthalten. Wer von Programmieren überhaupt nichts versteht, der wird an diesem Artikel wie gewohnt leider nichts finden können.

Der Praktikant ist offenbar ein großer Fan davon, toString() auf String-Objekten aufzurufen, vielleicht erhofft er sich dadurch noch stärkere Typsicherheit mit Netz und doppeltem Boden oder sowas. Jedenfalls Code wie der obige begegnet mir leider immer häufiger. Solchen Murks mache ich bei Sichtung auch sofort wieder raus.

Ebenfalls ein ständiger Begleiter in seinem Code: Die Angst, dass eine neu (=leer) angelegte Collection vielleicht doch nicht so leer ist, wie sie vorgibt zu sein. Anders kann ich mir nicht erklären, wieso der Praktikant gleich nach dem Erstellen einer leeren Collection diese leert. Womöglich hat er sich hierbei etwas gedacht, ist aber völlig unnützer Code. Ein damit sehr verwandtes Problem ist das folgende:

Aus der API-Dokumentation der oberen Methode: „The Calendar returned is based on the current time in the default time zone with the default locale.„. Der Knackpunkt ist, dass das zurückgegebene Kalender-Objekt immer bereits mit der gegenwärtigen Uhrzeit initialisiert ist. Hier (zur Sicherheit oder aus Unkenntnis) nochmals Uhrzeit und Datum zu setzen und dafür extra ein neues Date-Objekt zu erstellen, ist kompletter Unfug. Überhaupt: Wieso geht er davon aus, dass der parameterlose Konstruktor von Date() die aktuelle Uhrzeit liefert, aber bei Calendar soll selbiges System nicht funktionieren? Nett auch die Wahl des Variablennamens „actCal“ für den Kalender. Er dachte wohl, „actual calendar“ sei eine brauchbare Übersetzung für das, was er ausdrückten wollte. Ich lese da aber irgendwie immer nur „Aktkalender“.

Auch so ein Codekonstrukt, worüber man diskutieren sollte: die Getter-Methode für private Konstanten. Wieso nicht gleich die Konstante als public deklarieren, dann kann man sich das Rumgeeiere sparen. Bei Konstanten durchaus sinnvoll. Aber als verwandtes Problem sei angemerkt, dass der Praktikant zum Beispiel ganz gerne auch mal simple Getter-Methoden innerhalb derselben Klasse aufruft, in der sie definiert werden – anstelle der sichtbaren Variable. Kapselung schön und gut, aber damit ist doch eigentlich Kapselung von der Außenwelt gemeint. Das scheint jemand nicht so richtig verstanden zu haben.

Namenskonventionen für Methoden sind auch so ein Problem für den Praktikanten. Der Name der Methode sagt leider nichts darüber aus, was der Rückgabetyp sein könnte. Im Fall von „componentParser“ ist noch nicht einmal eine Tätigkeit erkennbar. Da meldet die als Frage formulierte Methode „isActive“ eine komplexe Hashmap zurück, und die etwas umständlich benannte Methode „getTheParsedSysInfoComp“ liefert nicht etwa „die kompletten Systeminformationen“ zurück, sondern einen Wahrheitswert – was auch immer dieser aussagen soll. Immer wieder lustig mitanzusehen sind Methodennamen, die erkennen lassen, dass sich dabei wohl jemand beim Ausdenken einen abbrechen musste, etwa „isLoadTimeFromOneSystemOverTime“.

Englisch scheint ohnehin nicht so seine ultimative Stärke zu sein, vor allem wenn die (netterweise konsequent, wenn auch unnötigerweise) im Englischen gehaltenen Kommentarzeilen nur so vor Denglisch triefen. Da wird aus „Pfade herausfiltern“ schonmal „filter the path outside“, oder das weibliche Possessivpronomen „her“ wird auf Systeme und _ihre_ Eigenschaften angewandt. Wenn man kein Englisch kann, sollte man vielleicht nicht unbedingt versuchen, alles immer englisch schreiben zu wollen, oder zumindest mal ein paar Vokabeln nachschlagen, bevor man in die Tasten haut.

Ich dachte bis heute morgen noch, ich sei mittlerweile lange genug Java-Entwickler, um vor solchen blöden Fehlern gefeit zu sein. Stellt sich heraus, dass man wirklich viel Zeit mit sinnloser Fehlersuche selbst in simpelstem Code verschwenden kann.

Heute schrieb ich etwas in meiner favorisierten Java-IDE Eclipse, das ich in der Art praktisch täglich unzählige Male schreibe:

List<String> myList = new ArrayList<String>();

List und ArrayList wurden mir rot unterstrichen, weil er die Klassen nicht kannte. Es dauert natürlich nur wenige Klicks und Eclipse generiert die fehlenden Imports blitzschnell. So weit so normal. Doch dann wird mir List erneut rot unterstrichen, mit der Fehlermeldung „The type List is not generic; it cannot be parameterized with arguments <String>„.

Ungläubig starrte ich die Fehlermeldung an. Ich war mir eigentlich total sicher, dass List Generics verwendet. Sicherer ging es fast nicht. Die Fehlermeldung sagte also genau das Gegenteil von dem aus, was meiner Ansicht nach den Tatsachen entsprechen sollte. Oder doch nicht? Plötzlich begann ich zu zweifeln. Werde ich etwa schon senil? Wieso ist ArrayList parametrisierbar, aber List auf einmal nicht? Ist das irgendwie sinnvoll?

Ich begann hilflos, die Zeile irgendwie zu modifizieren. War List auf einmal allergisch gegen String geworden? Nein, daran lag es nicht, auch andere Parameter nahm er nicht an. Ich hätte den Parameter weglassen können, oder ich hätte auch direkt ArrayList anstelle von List verwenden können, das hätte funktioniert, aber Eclipse sollte mich doch nicht etwa dazu kriegen, die wichtigsten Programmierparadigmen zu vergessen. Ich vermutete, dass Eclipse einfach mal wieder seine Tage hatte und mich zu Unrecht irgendwelcher Anfängerfehler beschuldigte. An der Zeile war alles in Ordnung, postulierte ich.

Ich begann also doch das Orakel von Google zu bemühen, weil ich offenbar außer Stande war, mir selbst bei solch einem trivialen Problem zu helfen. Eine Quelle behauptete nun, dass es wohl mit dem Compliance-Level des Compilers zu tun hatte, das versehentlich auf eine Version vor Java 1.5 gestellt sein musste, also bevor Generics in Java eingeführt wurden. Ein kurzer Blick in die Compiler-Optionen des Projekts widerlegte das. Mit dem Compliance-Level war alles in Ordnung. In Zukunft also wieder auf konkrete Implementierungen programmieren?

Zum Glück nicht, denn des Rätsels Lösung fand ich direkt im Anschluss, und ich bin erschrocken über die Tatsache, dass ich an dieser Stelle vielleicht erst ganz zuletzt gesucht hätte. Ich habe mich bei den Imports entweder verklickt oder Eclipse hat mich einfach nur auf den Arm nehmen wollen. Als ich List importieren wollte, habe ich wie automatisch die oberste Option ausgewählt, weil das in dem Fall normalerweise immer funktioniert. Ausnahmsweise dachte Eclipse, es wäre besonders witzig wenn ganz oben die wenig bekannte java.awt.List stehen würde, anstelle der sehr viel häufiger genutzten gleichnamigen Klasse java.util.List.

Nun, die AWT-List verwendet tatsächlich keine Generics, Eclipse hat also Recht behalten. Aber der Fehler ist so dämlich, dass es mir eine Lehre war, die Imports allzu leichtfertig zu handhaben. Künftig prüfe ich höchstpersönlich jede einzelne importierte Klasse auf Richtigkeit.

Java-Tutorials. Vor langer Zeit mal von mir angekündigt. Dann kam zu diesem Thema wieder nichts. Habe mir bisher einfach nicht die Zeit nehmen können, mir etwas zu überlegen, was gut in diese Rubrik passen könnte. Heute möchte ich aber zumindest mit einem sehr kleinen und recht simplen Beitrag beginnen, und wer weiß, vielleicht geht es danach ja sogar weiter. Je nachdem.

Kürzlich stand ich vor einem kleinen Problem, als ich in der Situation war, Daten über Lizenzen aus einem SAP-System auszulesen. Die Information lag in Form einer Tabelle als Vector<Vector<String>> vor. Aus diesem habe ich die benötigten Spalten in zwei String-Arrays rausgeschrieben: Lizenzkennzeichnung und das Gültigkeitsdatum. Diese Einträge sollten dann nach der Datums-Spalte sortiert werden. In diesem Augenblick fiel mir auf, dass ich keine spontane Idee hatte, wie ich zwei Arrays in Abhängigkeit voneinander sortieren sollte, also zwei Spalten gleichzeitig.

Eine Lösung des Problems ist mir dann aber nach kurzem Grübeln eingefallen: Eine passende Datenstruktur musste her, die ihre eigenen Sortierkriterien mitbringt:

Anschließend wollte ich einfach ein Array dieser Datenstruktur erzeugen und auf diesem toString() aufrufen, damit dann rekursiv alle toString()-Methoden seiner Elemente aufgerufen werden. Ach wie doof. So funktioniert das ja gar nicht. Kurzerhand habe ich mir also etwas ausgedacht, das toString() überschreibt, wie ich das gerne hätte:

Ich bin mir zwar relativ sicher, dass hier einige Java-Profis und Design-Pattern-Götter die Hände über dem Kopf zusammenschlagen werden, aber ich glaube ganz so unbrauchbar ist das eigentlich nicht. Und fragt mich schon gar nicht wieso ich da eine anonyme Klasse genommen habe. Vielleicht war ich einfach in der Stimmung dafür. Ich hoffe der Code ist selbsterklärend genug. Das meiste ist sowieso zu speziell, wichtig ist allein die Struktur.