Стойността на String.valueOf

Повечето разработчици на Java вероятно са изпълнили NullPointerException. Повечето от нас са научили колко е полезно да правим определени неща, за да намалим нашите „възможности“ за среща с NullPointerException. Всъщност има страница в Wiki, посветена на предотвратяването или намаляването на NullPointerExceptions.

Няколко души се аргументираха за допълнителна езикова поддръжка за подобрено и по-лесно боравене с потенциални null. Те включват предложения за SE SE 7, оптимизирана нулева проверка и тезата на Kinga Dobolyi Промяна на семантиката на Java за обработка на изключения от нулеви указатели.

Сред многото неща, които вече можем да направим доста лесно, за да намалим срещите си с NullPointerException, едно особено лесно нещо е да приложим String.valueOf (Object), когато е подходящо. В String.valueOf(Object)метода, тъй като неговите Javadoc генерирани документация държави, се връща "нула", ако премина в обект е nullи връща резултатите от мина в Objectе ToString () повикване, ако премина в Objectне е празно. С други думи, String.valueOf(String)проверява ли нулата вместо вас.

Използването на String.valueOf(Object)е особено полезно при внедряване на toStringметоди в персонализирани класове. Тъй като повечето toStringимплементации предоставят членовете на данните на класа във формат String, това String.valueOf(Object)е съвсем естествено. Всички Java обекти, базирани на класове, които разширяват Object, предоставят toString()реализация, дори ако това е просто Objectреализацията на техния родител (или дори ) toString(). Ако обаче член-член реализира, toStringно самият член е нула, а не екземпляр на класа, тогава това toString()не носи полза (и всъщност води до NullPointerExceptionизвикване).

Това се демонстрира със следния примерен код.

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); } } } 

Горният код може да се използва за демонстриране на изграждане на toStringметод върху сложен обект и как се държи той, когато е извикан от притежаващ клас. Най-интересният метод е в долната част на кода, показан по-горе. Две върнати стойности се коментират поради проблеми, свързани с тях. Последният пример, използването String.valueOf(Object)НЕ се коментира, защото работи най-добре всеки път, когато се изпълнява, независимо дали сложният PersonNameобект е нулев. Следващите три изображения показват изхода за всяка от тези презентации на представянето на String на обектите Person.

Стойност на низа от сложен обект - Грешка при компилиране

Стойност на низа от сложен обект toString () - Потенциално изпълнение по време на изпълнение NullPointerException

Стойност на низа от сложен обект String.valueOf () - Нули, обработени грациозно

Използването String.valueOf(Object)в toString()реализации може да бъде особено полезно, защото често използваме toString()метода при отстраняване на грешки и последното нещо, от което се нуждаем в такива случаи, е друго изключение, срещано при опит да видим текущото състояние на нашите данни. Разбира се, може да се приложат и toString()методи със собствени проверки за нула или, още по-добре, може да се използва нещо като ToStringBuilder. Наличието на String.valueOf(Object)със сигурност е нещо, което си струва да се има предвид и е нещо, което се оказвам, че използвам доста често. Много от нас откриха, че по-малко редове код обикновено са по-ясни и String.valueOf(Object)могат да бъдат много по-ясни от изричната проверка на обект за нула, преди да се извика неговото toString()изпълнение.

И накрая, класът String предоставя много претоварени методи valueOf. В допълнение към версията, която беше във фокуса на тази публикация в блога (приема обект), другите претоварени версии на valueOf приемат примитивни типове данни и масиви от примитивни типове данни.

Заключение

Независимо от това, което бъдещето носи по отношение на подобрената нулева обработка в Java, днес има много тактики, за да намалим нежеланите (понякога наистина искаме да бъдат хвърлени!) Появявания на NullPointerException. Едно от тях е да се използва, String.valueOf(Object)когато е подходящо.

Допълнителни ресурси

  • String.valueOf или Integer.toString ()?
  • Изрично срещу неявно извикване на toString
  • Стойността на низ с метод String.valueOf ()
  • Конвертиране на числото в низ

Тази история „Стойността на String.valueOf“ първоначално е публикувана от JavaWorld.