Okay, bevor ich anfange zu disskutieren. Schaut auch folgenden Codeschnipsel in Java an:
- String stringInt = "5";
- System.out.println("Integer.parseInt %d".formatted(Integer.parseInt(stringInt)));
- System.out.println("Integer.valueOf %d".formatted(Integer.valueOf(stringInt)));
- System.out.println("Integer.decode %d".formatted(Integer.decode(stringInt)));
- System.out.println("Ints.tryParse %d".formatted(Ints.tryParse(stringInt)));
- System.out.println("Scanner %d".formatted(new Scanner(stringInt).nextInt()));
- System.out.println("new Integer %d".formatted(new Integer(stringInt)));
- System.out.println("Character.getNumericValue %d".formatted(Character.getNumericValue(stringInt.charAt(0))));
- System.out.println("NumberUtils.toInt %d".formatted(NumberUtils.toInt(stringInt)));
- System.out.println("NumberUtils.stringToInt %d".formatted(NumberUtils.stringToInt(stringInt)));
Das Ergebnis dieses Schnipsels ist folgendes:
Fällt euch was auf?
Jede einzelne dieser Funktionsaufrufe tut das Selbe bzw. liefert das selbe Ergebnis. Ist das in anderen Programmiersprachen genauso schlimm?
Also für manche Hauseigene Funktionen von Java hab ich noch Verständnis. Zum Beispiel liefert
einen primitive int. Wohingegen
ein Integer Objekt liefert. Welches cached ist, ergo bis zu einem bestimmten Wert sind diese einmalig abgespeichert und im Speichert wird kein neuer Integer erstellt. Bei mir sinds aktuell die Werte im Wertebereich von -128 und 128, wohingegen der high wert anpassbar ist. Aber das nur nebenbei.
Ok, das sei Java geschenkt. Integer.valueOf ist ja auch deprecated, fällt also hoffentlich bald weg (Wenn auch das seit Java 9 deprecated ist.. Wir sind schon bei Java 17...)
ist einfach nur noch traurig. Es ist dafür da, um sowas wie "0x55" von HEX als String auf einen Integer zu mappen. 0x55 wären z.B 85 im Dezimalsystem. Der Code zu dieser Funktion sieht aber einfach nur traurig aus, samt Dependency zu anderen internen Funktionen, temporären Variablen, random magic strings mitten in der Funktion und vielen mehr. Aber seht selbst:
- public static Integer decode(String nm) throws NumberFormatException {
- int radix = 10;
- int index = 0;
- boolean negative = false;
- Integer result;
- if (nm.isEmpty())
- throw new NumberFormatException("Zero length string");
- char firstChar = nm.charAt(0);
- // Handle sign, if present
- if (firstChar == '-') {
- negative = true;
- index++;
- } else if (firstChar == '+')
- index++;
- // Handle radix specifier, if present
- if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
- index += 2;
- radix = 16;
- }
- else if (nm.startsWith("#", index)) {
- index ++;
- radix = 16;
- }
- else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
- index ++;
- radix = 8;
- }
- if (nm.startsWith("-", index) || nm.startsWith("+", index))
- throw new NumberFormatException("Sign character in wrong position");
- try {
- result = Integer.valueOf(nm.substring(index), radix);
- result = negative ? Integer.valueOf(-result.intValue()) : result;
- } catch (NumberFormatException e) {
- // If number is Integer.MIN_VALUE, we'll end up here. The next line
- // handles this case, and causes any genuine format error to be
- // rethrown.
- String constant = negative ? ("-" + nm.substring(index))
- : nm.substring(index);
- result = Integer.valueOf(constant, radix);
- }
- return result;
- }
Das sieht btw. 1:1 so aus, wie jede einzelne Funktion die YMIR jemals geschrieben hat. Das ist doch auch nicht performant, dass man es irgendwie so rechtfertigen könnte, wie die C++ Champions ihren Source Code rechtfertigen. ("Ja ist unlesbar, aber dafür schnell!" - Wer da keinen Fehler im Design erkennt, dem kann ich auch nicht helfen.)
Ok zurück zu Java, wir sind noch nicht fertig.
ruft einfach parseInt auf von oben mit dem zweiten Parameter "10" fürs Zahlensytem, was eh default ist. Also einfach nur ein anderer Name für eine Funktion. Aber warum?
Ok, auch diese Funktion ist deprecated, aber warum dachte jemals ein API Designer, dass das eine gute Idee wäre?
Jetzt kommen wir zu Librarys, die sich dachten: Es gibt noch nicht genug Wege, lass mal noch ein bisschen mehr reinscheißen!
ist von Google Guava und gibt null zurück falls der String nicht geparsed werden kann. Man ist also gezwungen den Integer am Ende auf 'null' zu prüfen, um damit zu arbeiten. Na super! Vllt. gut wo ein Nutzer einen String reingeben soll, aber da würd ich doch lieber das von Apache nutzen:
Hier kann man als zweiten Parameter einen default value reingeben, der bei so einem Exception case wie einem String wie "haha15" den default value returnen würde.
Die rufen intern auch nur Integer.parseInt auf. Hier ist der Code aber wenigstens lesbar.
Auf
geh ich jetzt nicht mehr ein, das wird nur noch traurig.
Meine Frage ist: Ist das nur in Java so? Ich denke, dass so Sprachen wie Python genau deshalb so beliebt sind und immer beliebter werden und warum Anfänger darauf schwören. Es gibt nur einen Weg etwas zu tun, keine 10. C++ dagegen sagt: Es gibt 10 Wege und bei 9/10 schießt du dir ins Knie. Nr. 10 wirft einen Segfault, du Hurensohn. Jetzt geh debuggen.
Ok, das war mein Rant.
Danke fürs Lesen, lasst mir gern eure Meinung da. Würde mich echt interessieren wie da eure Erfahrungen sind.