Der Wert von String.valueOf

Die meisten Java-Entwickler haben wahrscheinlich die NullPointerException satt. Die meisten von uns haben gelernt, wie wichtig es ist, bestimmte Dinge zu tun, um die "Möglichkeiten" zu verringern, auf die NullPointerException zu stoßen. In der Tat gibt es eine Wiki-Seite, die NullPointerExceptions verhindert oder reduziert.

Mehrere Personen haben sich für zusätzliche Sprachunterstützung ausgesprochen, um den Umgang mit potenziellen Nullen zu verbessern und zu vereinfachen. Dazu gehören Java SE 7-Vorschläge, Optimized Null Check und Kinga Dobolyis These Ändern der Java-Semantik für den Umgang mit Nullzeiger-Ausnahmen.

Unter den vielen Dingen, die wir bereits ziemlich einfach tun können, um unsere Begegnungen mit NullPointerException zu reduzieren, ist es besonders einfach, String.valueOf (Object) gegebenenfalls anzuwenden. Die String.valueOf(Object)Methode gibt, wie in der von Javadoc generierten Dokumentation angegeben, "null" zurück, wenn das übergebene Objekt ist, nullund gibt die Ergebnisse beim ObjectAufruf toString () des übergebenen Objekts zurück, wenn das übergebene Objekt Objectnicht null ist. Mit anderen Worten, String.valueOf(String)führt die Nullprüfung für Sie durch.

Die Verwendung von String.valueOf(Object)ist besonders nützlich, wenn toStringMethoden für benutzerdefinierte Klassen implementiert werden. Da die meisten toStringImplementierungen die Datenelemente der Klasse im String-Format bereitstellen, String.valueOf(Object)ist dies eine natürliche Anpassung. Alle Java-Objekte, die auf Klassen basieren, die Object erweitern, bieten eine toString()Implementierung, auch wenn es sich lediglich um die Implementierung ihrer Eltern (oder sogar der Eltern Object) handelt toString(). Wenn jedoch eine Member-Klasse implementiert wird toString, das Member selbst jedoch null ist und keine Instanz der Klasse, dann toString()nützt das nichts (und führt tatsächlich zu einem NullPointerExceptionAufruf).

Dies wird anhand des folgenden Beispielcodes demonstriert.

StringHandlingExample.java

package dustin.examples; import java.io.IOException; import java.io.OutputStream; import java.util.logging.Logger; /** * Example class demonstrating use of String representations available through * implicit String, toString(), and String.valueOf(). */ public class StringHandlingExample { private static final String NEW_LINE = System.getProperty("line.separator"); /** Using java.util.logging. */ private static Logger LOGGER = Logger.getLogger( StringHandlingExample.class.getName()); /** * Main function for running tests/demonstrations. * * @param arguments Command-line arguments; none anticipated. */ public static void main(final String[] arguments) { printHeader("String representation of direct Strings", System.out); final PersonName personName = new PersonName("Flintstone", null); System.out.println("Person's Name [DIRECT]: " + personName); System.out.println("Person's Name [TOSTRING]: " + personName.toString()); System.out.println("Person's Name [STRING.VALUEOF]: " + String.valueOf(personName)); printBlankLine(System.out); printHeader("String representation of non-null complex object", System.out); final Person personOne = new Person(personName); System.out.println("Person One [DIRECT]: " + personOne); System.out.println("Person One [TOSTRING]: " + personOne.toString()); System.out.println("Person One [STRING.VALUEOF]: " + String.valueOf(personOne)); printBlankLine(System.out); printHeader("String representation of null complex object", System.out); final Person personTwo = new Person(null); System.out.println("Person Two [DIRECT]: " + personTwo); System.out.println("Person Two [TOSTRING]: " + personTwo.toString()); System.out.println("Person Two [STRING.VALUEOF]: " + String.valueOf(personTwo)); printBlankLine(System.out); } public static void printHeader(final String message, final OutputStream out) { final String headerSeparator = "===================================================================="; try { out.write((headerSeparator + NEW_LINE + message + NEW_LINE).getBytes()); out.write((headerSeparator + NEW_LINE).getBytes()); } catch (IOException ioEx) { System.out.println(headerSeparator); System.out.println(message); System.out.println(headerSeparator); LOGGER.warning("Could not write header information to provided OutputStream."); } } public static void printBlankLine(final OutputStream out) { try { out.write(NEW_LINE.getBytes()); } catch (IOException ioEx) { System.out.println(NEW_LINE); LOGGER.warning("Could not write blank line to provided OutputStream."); } } /** * Class upon which to call toString. */ private static class PersonName { private String lastName; private String firstName; public PersonName(final String newLastName, final String newFirstName) { lastName = newLastName; firstName = newFirstName; } /** * Provide String representation of me. * * @return My String representation. */ @Override public String toString() { return firstName + " " + lastName; } } private static class Person { private PersonName name; public Person(final PersonName newName) { name = newName; } /** * Provide String representation of me. * * @return My String representation. */ public String toString() { // Don't use -- leads to compiler time error (incompatible types) //return name; // Don't use -- can lead to runtime error (NullPointerException) //return name.toString(); // It's all good return String.valueOf(name); } } } 

Der obige Code kann verwendet werden, um die Erstellung einer toStringMethode für ein komplexes Objekt und dessen Verhalten beim Aufruf durch eine besitzende Klasse zu demonstrieren . Die Methode von größtem Interesse befindet sich am Ende des oben gezeigten Codes. Zwei Rückgabewerte werden aufgrund der damit verbundenen Probleme auskommentiert. Das letzte Beispiel mit String.valueOf(Object)wird NICHT auskommentiert, da es bei jeder Ausführung am besten funktioniert, unabhängig davon, ob das komplexe PersonNameObjekt null ist oder nicht . Die nächsten drei Bilder zeigen die Ausgabe für jede dieser Präsentationen der String-Darstellungen der Personenobjekte.

Zeichenfolgenwert aus komplexem Objekt - Fehler beim Kompilieren

Zeichenfolgenwert vom komplexen Objekt zu String () - Potenzielle Laufzeit-NullPointerException

String-Wert aus komplexem Objekt String.valueOf () - Nullen werden ordnungsgemäß behandelt

Die Verwendung String.valueOf(Object)in toString()Implementierungen kann besonders vorteilhaft sein, da wir die toString()Methode häufig beim Debuggen verwenden und das Letzte, was wir in solchen Fällen benötigen, eine weitere Ausnahme ist, die beim Versuch auftritt, den aktuellen Status unserer Daten anzuzeigen. Natürlich kann man auch toString()Methoden mit eigenen Prüfungen auf Null implementieren oder, noch besser, so etwas wie ToStringBuilder verwenden. Die Verfügbarkeit von String.valueOf(Object)ist jedoch sicherlich etwas, das es wert ist, beachtet zu werden, und das ich ziemlich oft benutze. Viele von uns haben festgestellt, dass weniger Codezeilen im Allgemeinen klarer sind und String.valueOf(Object)viel klarer sein können, als ein Objekt explizit auf Null zu prüfen, bevor seine toString()Implementierung aufgerufen wird .

Schließlich bietet die String-Klasse viele überladene valueOf-Methoden. Zusätzlich zu der Version, die im Mittelpunkt dieses Blogposts stand (akzeptiert ein Objekt), akzeptieren die anderen überladenen Versionen von valueOf primitive Datentypen und Arrays primitiver Datentypen.

Fazit

Unabhängig davon, was die Zukunft in Bezug auf eine verbesserte Nullbehandlung in Java mit sich bringt, können wir heute viele Taktiken anwenden, um das unerwünschte Auftreten von NullPointerException zu reduzieren (manchmal wollen wir sie tatsächlich auslösen!). Eine davon ist String.valueOf(Object)gegebenenfalls zu verwenden.

Zusätzliche Ressourcen

  • String.valueOf oder Integer.toString ()?
  • Expliziter versus impliziter Aufruf von toString
  • Der Wert eines Strings mit der String.valueOf () -Methode
  • Nummer in String konvertieren

Diese Geschichte "The Value of String.valueOf" wurde ursprünglich von JavaWorld veröffentlicht.