Ich habe ein Projekt, in dem wir oft Integer.parseInt()
einen String in einen Int konvertieren. Wenn etwas schief geht (zum Beispiel ist das String
keine Zahl, sondern der Buchstabe a
oder was auch immer), löst diese Methode eine Ausnahme aus. Wenn ich jedoch überall Ausnahmen in meinem Code behandeln muss, sieht dies sehr schnell sehr hässlich aus. Ich möchte dies in eine Methode einfügen, habe jedoch keine Ahnung, wie ein sauberer Wert zurückgegeben werden soll, um zu zeigen, dass die Konvertierung fehlgeschlagen ist.
In C ++ hätte ich eine Methode erstellen können, die einen Zeiger auf ein int akzeptiert und die Methode selbst true oder false zurückgeben lässt. Soweit ich weiß, ist dies in Java jedoch nicht möglich. Ich könnte auch ein Objekt erstellen, das eine True / False-Variable und den konvertierten Wert enthält, aber dies scheint auch nicht ideal zu sein. Das Gleiche gilt für einen globalen Wert, und dies könnte mir Probleme mit Multithreading bereiten.
Gibt es also einen sauberen Weg, dies zu tun?
quelle
int
2147483648 nicht.Antworten:
Sie könnten eine Rückkehr
Integer
anstelle einerint
, Rückkehrnull
auf Parse - Ausfall.Es ist eine Schande, dass Java keine Möglichkeit bietet, dies zu tun, ohne dass eine Ausnahme intern ausgelöst wird. Sie können die Ausnahme ausblenden (indem Sie sie abfangen und null zurückgeben), aber es kann immer noch ein Leistungsproblem sein, wenn Sie Hunderte analysieren von Tausenden von Bits von vom Benutzer bereitgestellten Daten.
EDIT: Code für eine solche Methode:
Beachten Sie, dass ich mir nicht sicher bin, was dies tun wird, wenn
text
es null ist. Sie sollten Folgendes berücksichtigen: Wenn es sich um einen Fehler handelt (dh Ihr Code kann einen ungültigen Wert übergeben, aber niemals null übergeben), ist das Auslösen einer Ausnahme angemessen. Wenn es keinen Fehler darstellt, sollten Sie wahrscheinlich wie bei jedem anderen ungültigen Wert einfach null zurückgeben.Ursprünglich verwendete diese Antwort den
new Integer(String)
Konstruktor; es verwendet jetztInteger.parseInt
und eine Boxoperation; Auf diese Weise werden kleine Werte in zwischengespeicherteInteger
Objekte gepackt , was sie in diesen Situationen effizienter macht.quelle
null
Referenzen zu überprüfen, als Ausnahmen regelmäßig zu behandeln.Welches Verhalten erwarten Sie, wenn es keine Zahl ist?
Wenn Sie beispielsweise häufig einen Standardwert verwenden müssen, wenn die Eingabe keine Zahl ist, kann eine solche Methode hilfreich sein:
Ähnliche Methoden können für ein anderes Standardverhalten geschrieben werden, wenn die Eingabe nicht analysiert werden kann.
quelle
In einigen Fällen sollten Sie Analysefehler als ausfallsichere Situationen behandeln, in anderen Fällen, z. B. bei der Anwendungskonfiguration, bevorzuge ich die Behandlung fehlender Eingaben mit Standardwerten mithilfe von Apache Commons Lang 3 NumberUtils .
quelle
Um die Behandlung von Ausnahmen zu vermeiden, verwenden Sie einen regulären Ausdruck, um sicherzustellen, dass Sie zuerst alle Ziffern haben:
quelle
Es gibt
Ints.tryParse()
in Guave . Es wird keine Ausnahme für nicht numerische Zeichenfolgen ausgelöst, jedoch keine Ausnahme für Nullzeichenfolgen.quelle
Nach dem Lesen der Antworten auf die Frage denke ich, dass das Einkapseln oder Umschließen der parseInt-Methode nicht erforderlich ist, vielleicht sogar keine gute Idee.
Sie könnten 'null' zurückgeben, wie Jon vorgeschlagen hat, aber das ersetzt mehr oder weniger ein try / catch-Konstrukt durch eine Null-Prüfung. Es gibt nur einen kleinen Unterschied im Verhalten, wenn Sie die Fehlerbehandlung "vergessen": Wenn Sie die Ausnahme nicht abfangen, gibt es keine Zuweisung und die Variable auf der linken Seite behält den alten Wert bei. Wenn Sie nicht auf Null testen, werden Sie wahrscheinlich von der JVM (NPE) getroffen.
Der Vorschlag von yawn sieht für mich eleganter aus, weil ich es nicht mag, null zurückzugeben, um einige Fehler oder außergewöhnliche Zustände anzuzeigen. Jetzt müssen Sie die referenzielle Gleichheit mit einem vordefinierten Objekt überprüfen, das auf ein Problem hinweist. Aber wie andere argumentieren, wenn Sie erneut die Überprüfung vergessen und ein String nicht analysierbar ist, setzt das Programm das umschlossene Int in Ihrem 'ERROR'- oder' NULL'-Objekt fort.
Die Lösung von Nikolay ist noch objektorientierter und funktioniert auch mit parseXXX-Methoden aus anderen Wrapper-Klassen. Am Ende hat er jedoch nur die NumberFormatException durch eine OperationNotSupported-Ausnahme ersetzt. Auch hier benötigen Sie einen Versuch / Fang, um nicht analysierbare Eingaben zu verarbeiten.
Daher ist es meine Schlussfolgerung, die einfache parseInt-Methode nicht zu kapseln. Ich würde nur einkapseln, wenn ich auch eine (anwendungsabhängige) Fehlerbehandlung hinzufügen könnte.
quelle
Vielleicht können Sie so etwas verwenden:
quelle
Sie können das gewünschte C ++ - Verhalten auch ganz einfach replizieren
Sie würden die Methode wie folgt verwenden:
Danach ist die Variable
result
wahr, wenn alles in Ordnung ist undbyRef[0]
den analysierten Wert enthält.Persönlich würde ich mich an die Ausnahme halten.
quelle
Die Antwort von Jon Skeet ist in Ordnung, aber ich gebe kein
null
Integer-Objekt zurück. Ich finde das verwirrend zu benutzen. Seit Java 8 gibt es (meiner Meinung nach) eine bessere OptionOptionalInt
:Dies macht deutlich, dass Sie den Fall behandeln müssen, in dem kein Wert verfügbar ist. Ich würde es vorziehen, wenn diese Art von Funktion in Zukunft zur Java-Bibliothek hinzugefügt würde, aber ich weiß nicht, ob dies jemals passieren wird.
quelle
Wenn Sie Java 8 oder höher verwenden, können Sie eine Bibliothek verwenden, die ich gerade veröffentlicht habe: https://github.com/robtimus/try-parse . Es unterstützt int, long und boolean, ohne dass Ausnahmen abgefangen werden müssen. Im Gegensatz zu Ints.tryParse von Guava wird OptionalInt / OptionalLong / Optional zurückgegeben, ähnlich wie in https://stackoverflow.com/a/38451745/1180351, jedoch effizienter.
quelle
Mein Java ist etwas rostig, aber lassen Sie mich sehen, ob ich Sie in die richtige Richtung weisen kann:
Wenn Ihr Rückgabewert ist
null
, haben Sie einen schlechten Wert. Ansonsten haben Sie eine gültigeInteger
.quelle
Integer.tryParse
In der Standard-Java-Integer
Klasse gibt es keine . 2. Diesnew Integer
ist nicht erforderlich (und wird dagegen empfohlen), da Java das Boxen und Entpacken automatisch durchführt. Ihr Java ist nicht nur ein bisschen rostig, es ist auch sehr rostig.Was ist mit dem Verzweigen der parseInt- Methode?
Es ist einfach, einfach kopieren und einfügen den Inhalt in ein neues Dienstprogramm , dass die Rendite
Integer
oderOptional<Integer>
und mit Renditen wirft ersetzen. Es scheint, dass es keine Ausnahmen im zugrunde liegenden Code gibt, aber besser überprüfen .Durch Überspringen der gesamten Ausnahmebehandlung können Sie bei ungültigen Eingaben Zeit sparen. Und die Methode gibt es seit JDK 1.0, sodass Sie wahrscheinlich nicht viel tun müssen, um sie auf dem neuesten Stand zu halten.
quelle
Ich würde vorschlagen, dass Sie eine Methode wie in Betracht ziehen
die Sie dann nach Belieben implementieren. Wenn Sie möchten, dass das Ergebnis zurückgeführt wird - möglicherweise weil Sie Integer.parseInt () trotzdem verwenden -, können Sie den Array-Trick verwenden.
Hier setzen Sie das Ergebnis [0] auf den im Prozess gefundenen ganzzahligen Wert.
quelle
Dies ähnelt etwas der Lösung von Nikolay:
Die Hauptmethode demonstriert den Code. Eine andere Möglichkeit, die Parser-Schnittstelle zu implementieren, besteht offensichtlich darin, einfach "\ D +" aus der Konstruktion zu setzen und die Methoden nichts tun zu lassen.
quelle
Sie könnten Ihre eigenen rollen, aber es ist genauso einfach, die
StringUtils.isNumeric()
Methode von commons lang zu verwenden . Es verwendet Character.isDigit () , um jedes Zeichen in der Zeichenfolge zu durchlaufen.quelle
Die Art und Weise, wie ich mit diesem Problem umgehe, ist rekursiv. Zum Beispiel beim Lesen von Daten von der Konsole:
quelle
Um eine Ausnahme zu vermeiden, können Sie die Java-
Format.parseObject
Methode verwenden. Der folgende Code ist im Grunde eine vereinfachte Version der IntegerValidator- Klasse von Apache Common .Sie können je nach Wunsch entweder
AtomicInteger
denint[]
Array-Trick oder den Array-Trick verwenden.Hier ist mein Test, der es verwendet -
quelle
Ich hatte auch das gleiche Problem. Dies ist eine Methode, die ich geschrieben habe, um den Benutzer nach einer Eingabe zu fragen und die Eingabe nur zu akzeptieren, wenn es sich um eine Ganzzahl handelt. Bitte beachten Sie, dass ich ein Anfänger bin. Wenn der Code nicht wie erwartet funktioniert, beschuldigen Sie meine Unerfahrenheit!
quelle
Dies ist eine Antwort auf die Frage 8391979 "Hat Java eine int.tryparse, die keine Ausnahme für fehlerhafte Daten auslöst? [Duplikat]", die geschlossen und mit dieser Frage verknüpft ist.
Edit 2016 08 17: ltrimZeroes-Methoden hinzugefügt und in tryParse () aufgerufen. Ohne führende Nullen in numberString können falsche Ergebnisse erzielt werden (siehe Kommentare im Code). Es gibt jetzt auch die öffentliche statische String ltrimZeroes-Methode (String numberString), die für positive und negative "Zahlen" funktioniert (END Edit).
Unten finden Sie eine rudimentäre Wrapper (Boxing) -Klasse für int mit einer hochgeschwindigkeitsoptimierten tryParse () -Methode (ähnlich wie in C #), die den String selbst analysiert und etwas schneller als Integer.parseInt (String s) aus Java ist:
Test- / Beispielprogramm für die Klasse IntBoxSimple:
quelle
Versuchen Sie es mit einem regulären Ausdruck und einem Standardparameterargument
Wenn Sie apache.commons.lang3 verwenden, verwenden Sie NumberUtils :
quelle
Ich möchte einen weiteren Vorschlag einbringen, der funktioniert, wenn speziell Ganzzahlen angefordert werden: Verwenden Sie einfach long und Long.MIN_VALUE für Fehlerfälle. Dies ähnelt dem Ansatz, der für Zeichen in Reader verwendet wird, wobei Reader.read () eine Ganzzahl im Bereich eines Zeichens oder -1 zurückgibt, wenn der Leser leer ist.
Für Float und Double kann NaN auf ähnliche Weise verwendet werden.
quelle
In Anbetracht der vorhandenen Antworten habe ich den Quellcode für
Integer.parseInt
meine Arbeit und meine Lösung kopiert und erweitertInts.tryParse()
),int[]
,Box
,OptionalInt
),CharSequence
oder einen Teil davon anstelle eines GanzenString
,Integer.parseInt
kann, dh [2,36],Der einzige Nachteil ist, dass es keinen Unterschied zwischen
toIntOfDefault("-1", -1)
und gibttoIntOrDefault("oops", -1)
.quelle
Sie können ein Null-Objekt wie folgt verwenden:
Das Ergebnis von main in diesem Beispiel ist:
Auf diese Weise können Sie immer auf fehlgeschlagene Konvertierung testen und trotzdem mit den Ergebnissen als Integer-Instanzen arbeiten. Möglicherweise möchten Sie auch die Zahl anpassen, die NULL darstellt (≠ 0).
quelle
Sie sollten keine Ausnahmen verwenden, um Ihre Werte zu überprüfen .
Für einzelne Zeichen gibt es eine einfache Lösung:
Für längere Werte ist es besser, einige Utils zu verwenden. Von Apache bereitgestellte NumberUtils würden hier perfekt funktionieren:
Bitte überprüfen Sie https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html
quelle
Integer.parseInt
.