Примитивные типы не имеют "toString" ... поэтому String.valueOfиспользуется. Для объектов, которые переопределяют toString, я думаю, что String.valueOf может вызвать это вместо этого. Не уверен насчет этой части.
Брэндон
@Brandon Вы правы, он делает именно это, за исключением того, что nullсначала проверяет .
azurefrog
Первый комментарий здесь, я думаю, имеет наибольший смысл, если он правильный. Вы должны использовать String.valueOf в определенных ситуациях, когда целью является примитивный тип.
если аргумент равен null, то строка равна "null"; в противном случае obj.toString()возвращается значение.
Так что на самом деле не должно быть никакой разницы, кроме вызова дополнительного метода.
Кроме того, в случае Object#toString, если экземпляр есть null, NullPointerExceptionбудет брошен a , поэтому, возможно, это менее безопасно .
publicstaticvoid main(String args[]){String str =null;System.out.println(String.valueOf(str));// This will print a String equal to "null" System.out.println(str.toString());// This will throw a NullPointerException}
Это лучший ответ. Читайте и полагайтесь на javadocs, а не на код. (Код в принципе может отличаться для разных версий / выпусков Java.)
Stephen C
7
@Brandon - Неверно. Его нужно только изменить, если поведение изменится таким образом, что javadoc станет недействительным. 1) Шансы на то, что это произойдет для этого метода, НУЛЬ. Они не будут вносить изменения, которые требуют изменения спецификации, а если они это сделают, то они изменят спецификацию. 2) Это не отменяет мой совет. Если вы прочитаете javadoc, то увидите, что задокументированное поведение изменилось!
Stephen C
2
Разве метод, вызывающий исключение, не был бы более безопасным? Обычно, когда ваш код выдает исключение NullPointerException, это вроде как хорошо. В данный момент разработчику это может показаться неприятным («Ой, нет, теперь мне нужно вернуться и исправить мой код»), но, поскольку возникла ошибка, вы обнаружили, что вам нужно что-то исправить. В противном случае вы показываете «нуль» непосредственно пользователю и не получаете сообщения об ошибке, если вы явно не проверите его, что мне кажется менее безопасным.
Тим М.
1
Чтобы было ясно, вы не можете на самом деле звонить String.valueOf(null), это NPE. Он работает только для нулевых объектов.
Ноумен
1
Это не объяснение. String.valueOf(null)Фактически решает к valueOf(char[])перегрузке. Это потому, что char[]это более конкретный тип, чем Object.
Stephen C
17
Различия между String.valueOf (Object) и Object.toString ():
1) Если строка нулевая,
String.valueOf(Object)вернет null, тогда как Object::toString()вызовет исключение с нулевым указателем.
publicstaticvoid main(String args[]){String str =null;System.out.println(String.valueOf(str));// it will print null System.out.println(str.toString());// it will throw NullPointerException }
2) Подпись:
valueOf () класса String является статическим. тогда как метод toString () класса String нестатичен.
Подпись или синтаксис строкового метода valueOf () приведены ниже:
В Java есть ли разница между String.valueOf (Object) и Object.toString ()?
Да. (И тем более, если учесть перегрузку!)
Как объясняется в javadoc , метод String.valueOf((Object) null)будет рассматривать как особый случай, valueOfи значение "null"будет возвращено. Напротив, null.toString()просто даст вам NPE.
перегрузка
Оказывается, String.valueOf(null)(обратите внимание на разницу!) Действительно дает NPE ... несмотря на javadoc. Объяснение неясное:
Существует ряд перегрузок String.valueOf, но здесь важны две: String.valueOf(Object)и String.valueOf(char[]).
В выражении применимыString.valueOf(null) обе эти перегрузки , поскольку присваивание совместимо с любым ссылочным типом.null
При наличии двух или более применимых перегрузок JLS сообщает, что выбрана перегрузка для наиболее конкретного типа аргумента.
Поскольку char[]это подтип Object, он более конкретен .
Поэтому String.valueOf(char[])перегрузка называется.
String.valueOf(char[])выдает NPE, если его аргумент является нулевым массивом. В отличие от этого String.valueOf(Object), это не рассматривается nullкак особый случай.
(Вы можете подтвердить это, используя javap -cдля проверки кода метода, который вызывает String.valueOf(null)вызов. Обратите внимание на перегрузку, которая используется для вызова.)
Другой пример valueOf(char[])еще яснее иллюстрирует разницу в перегрузке:
char[] abc =newchar[]('a','b','c');System.out.println(String.valueOf(abc));// prints "abc"System.out.println(abc.toString());// prints "[C@...."
Есть ли для них особые правила кода?
Нет.
Используйте то, что лучше всего соответствует требованиям контекста, в котором вы его используете. (Вам нужно форматирование для работы null?)
Примечание: это не соглашение о коде. Это просто программирование на основе здравого смысла. Более важно, чтобы ваш код был правильным, чем следовать каким-то стилистическим соглашениям или догме "передовой практики".
Личное мнение:
Некоторые разработчики приобретают (IMO) дурную привычку «защищаться» от нулей. Итак, вы видите множество тестов на пустые значения и рассматриваете нули как особые случаи. Идея, кажется, состоит в том, чтобы предотвратить появление NPE.
Я думаю, что это плохая идея. В частности, я думаю, что это плохая идея, если то, что вы делаете, когда вы обнаруживаете, - nullэто попытки «исправить» ... без учета того, почему он там был null.
В общем, лучше вообще не nullбыть там ... если только это не nullимеет очень конкретного значения в вашем приложении или дизайне API. Таким образом, вместо того, чтобы избегать NPE с большим количеством защитного кодирования, лучше позволить NPE произойти, а затем отследить и исправить источник непредвиденного null, вызвавшего NPE.
Итак, как это применимо здесь?
Что ж, если вы думаете об этом, использование String.valueOf(obj)могло бы быть способом "исправления положения". Этого следует избегать. Если неожиданно objоказаться nullв контексте, лучше использовать obj.toString().
Большинство из них уже упоминалось в других ответах, но я просто добавляю его для полноты:
Примитивы не имеют, так .toString()как они не являются реализацией Objectкласса -class, поэтому String.valueOfмогут использоваться только.
String.valueOfпреобразует данный объект nullв String "null", тогда как .toString()вызовет NullPointerException.
Компилятор будет использовать String.valueOfпо умолчанию, когда используется что-то вроде String s = "" + (...);. Вот почему в Object t = null; String s = "" + t;результате будет строка "null", а не NPE. РЕДАКТИРОВАТЬ: На самом деле он будет использовать StringBuilder.append, а не String.valueOf. Так что игнорируйте то, что я здесь сказал.
В дополнение к этому, вот пример использования, когда String.valueOfи .toString()имеют разные результаты:
Допустим, у нас есть такой общий метод:
publicstatic<T> T test(){String str ="test";return(T) str;}
И мы будем называть его с Integerтипом , как это: Main.<Integer>test().
Когда мы создаем String, String.valueOfон отлично работает:
При использовании .toString()он сначала компилировать и оценивать объект, в котором приведение к T(который является Stringк Integerотлит в данном случае) приведет к ClassCastException.
При использовании String.valueOfон будет видеть общий файл, Tкак Objectво время компиляции, и даже не заботится о том, чтобы он был Integer. Таким образом, он будет приводить Objectк Object(что компилятор просто игнорирует). Затем он будет использовать String.valueOf(Object), что приведет к Stringожидаемому результату. Таким образом, даже несмотря на String.valueOf(Object)то, .toString()что внутри параметра будет выполняться a , мы уже пропустили приведение и обработали его как an Object, поэтому мы избежали того, ClassCastExceptionчто происходит с использованием .toString().
Просто подумал, что стоит упомянуть эту дополнительную разницу между String.valueOfи .toString()здесь.
В прошлый раз, когда я заботился об этом, это было бы около JDK 1.2, ("" + x)скомпилированное в String.valueOf(x), но для чего-то более сложного использовался StringBuffer(тогда у нас не было StringBuilder).
Нил
4
String.valueOf(Object)и Object.toString()буквально одно и то же.
Если вы посмотрите на реализацию String.valueOf (Object) , вы увидите, что String.valueOf(Object)это в основном просто нулевой безопасный вызов toString()соответствующего объекта:
Returns the string representation of the Object argument.Parameters:
obj an Object.Returns:if the argument is null, then a string equal to "null";
otherwise, the value of obj.toString() is returned.See also:Object.toString()publicstaticString valueOf(Object obj){return(obj ==null)?"null": obj.toString();}
Есть еще одно важное различие между этими двумя методами: когда объект, который мы конвертируем, является массивом.
Когда вы конвертируете массив с помощью Object.toString (), вы получите какое-то значение мусора (@, за которым следует хэш-код массива).
Чтобы получить удобочитаемый toString (), вы должны использовать String.valueOf (char []); Пожалуйста, обратите внимание, что этот метод работает только для массива типа char. Я бы рекомендовал использовать Arrays.toString (Object []) для преобразования массивов в String.
Второе отличие заключается в том, что когда объект имеет значение NULL, ValueOf () возвращает String «null», а toString () возвращает исключение с нулевым указателем.
Привет, @Tom, это верно для массива любого типа, однако, если вы используете Arrays.toString (Object []), вы можете преобразовать массив любого типа в строку.
chintan thakker
Привет @Tom Object.toString (), возвращающий значение мусора, верно для массива любого типа, вы правы, что String.valueOf (Array) даст правильную строку только для массива типа char. Я должен был упомянуть, что спасибо, я его отредактирую.
chintan thakker
1
Это не мусорное значение, это имя класса и хэш-код ( JavaDoc ).
Tom
-1
Я не могу точно сказать, в чем разница, но кажется разница при работе на уровне байтов. В следующем сценарии шифрования Object.toString () выдал значение, которое не удалось расшифровать, тогда как String.valueOf () работал по назначению ...
privatestaticchar[] base64Encode(byte[] bytes){returnBase64.encode(bytes);}privatestaticString encrypt(String encrypt_this)throwsGeneralSecurityException,UnsupportedEncodingException{SecretKeyFactory keyFactory =SecretKeyFactory.getInstance("PBEWithMD5AndDES");SecretKey key = keyFactory.generateSecret(newPBEKeySpec(PASSWORD));Cipher pbeCipher =Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key,newPBEParameterSpec(SALT,20));//THIS FAILED when attempting to decrypt the password//return base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))).toString(); //THIS WORKEDreturnString.valueOf(base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))));}//end of encrypt()
Объяснение заключается в том, что вы на самом деле звоните, valueOf(char[])а не valueOf(Object). Поведение valueOf(char[])существенно отличается от char[].toString(). Но так или иначе, этот ответ не по поводу , потому что вы вызываете другую перегрузку в один Вопрос спрашивает о.
Стивен С.
-1
И в большинстве случаев лучше возвращать NPE, чем "нулевое" значение.
Ниже показана реализация java.lang.String.valueOf, как описано в исходном коде jdk8u25. Итак, согласно моему комментарию, разницы нет. Он вызывает Object.toString. Для примитивных типов он оборачивает его в объектную форму и вызывает для него «toString».
Увидеть ниже:
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/publicstaticString valueOf(Object obj){return(obj ==null)?"null": obj.toString();}publicstaticString valueOf(char data[]){returnnewString(data);}publicstaticString valueOf(char data[],int offset,int count){returnnewString(data, offset, count);}publicstaticString copyValueOf(char data[],int offset,int count){returnnewString(data, offset, count);}publicstaticString copyValueOf(char data[]){returnnewString(data);}publicstaticString valueOf(boolean b){return b ?"true":"false";}publicstaticString valueOf(char c){char data[]={c};returnnewString(data,true);}publicstaticString valueOf(int i){returnInteger.toString(i);}publicstaticString valueOf(long l){returnLong.toString(l);}publicstaticString valueOf(float f){returnFloat.toString(f);}publicstaticString valueOf(double d){returnDouble.toString(d);}
String.valueOf
используется. Для объектов, которые переопределяют toString, я думаю, что String.valueOf может вызвать это вместо этого. Не уверен насчет этой части.null
сначала проверяет .Ответы:
Согласно документации Java ,
String.valueOf()
возвращает:Так что на самом деле не должно быть никакой разницы, кроме вызова дополнительного метода.
Кроме того, в случае
Object#toString
, если экземпляр естьnull
,NullPointerException
будет брошен a , поэтому, возможно, это менее безопасно .источник
String.valueOf(null)
, это NPE. Он работает только для нулевых объектов.String.valueOf(null)
Фактически решает кvalueOf(char[])
перегрузке. Это потому, чтоchar[]
это более конкретный тип, чемObject
.Различия между String.valueOf (Object) и Object.toString ():
1) Если строка нулевая,
String.valueOf(Object)
вернетnull
, тогда какObject::toString()
вызовет исключение с нулевым указателем.2) Подпись:
valueOf () класса String является статическим. тогда как метод toString () класса String нестатичен.
Подпись или синтаксис строкового метода valueOf () приведены ниже:
Подпись или синтаксис строкового
toString()
метода приведены ниже:источник
Да. (И тем более, если учесть перегрузку!)
Как объясняется в javadoc , метод
String.valueOf((Object) null)
будет рассматривать как особый случай,valueOf
и значение"null"
будет возвращено. Напротив,null.toString()
просто даст вам NPE.перегрузка
Оказывается,
String.valueOf(null)
(обратите внимание на разницу!) Действительно дает NPE ... несмотря на javadoc. Объяснение неясное:Существует ряд перегрузок
String.valueOf
, но здесь важны две:String.valueOf(Object)
иString.valueOf(char[])
.В выражении применимы
String.valueOf(null)
обе эти перегрузки , поскольку присваивание совместимо с любым ссылочным типом.null
При наличии двух или более применимых перегрузок JLS сообщает, что выбрана перегрузка для наиболее конкретного типа аргумента.
Поскольку
char[]
это подтипObject
, он более конкретен .Поэтому
String.valueOf(char[])
перегрузка называется.String.valueOf(char[])
выдает NPE, если его аргумент является нулевым массивом. В отличие от этогоString.valueOf(Object)
, это не рассматриваетсяnull
как особый случай.(Вы можете подтвердить это, используя
javap -c
для проверки кода метода, который вызываетString.valueOf(null)
вызов. Обратите внимание на перегрузку, которая используется для вызова.)Другой пример
valueOf(char[])
еще яснее иллюстрирует разницу в перегрузке:Нет.
Используйте то, что лучше всего соответствует требованиям контекста, в котором вы его используете. (Вам нужно форматирование для работы
null
?)Примечание: это не соглашение о коде. Это просто программирование на основе здравого смысла. Более важно, чтобы ваш код был правильным, чем следовать каким-то стилистическим соглашениям или догме "передовой практики".
Личное мнение:
Некоторые разработчики приобретают (IMO) дурную привычку «защищаться» от нулей. Итак, вы видите множество тестов на пустые значения и рассматриваете нули как особые случаи. Идея, кажется, состоит в том, чтобы предотвратить появление NPE.
Я думаю, что это плохая идея. В частности, я думаю, что это плохая идея, если то, что вы делаете, когда вы обнаруживаете, -
null
это попытки «исправить» ... без учета того, почему он там былnull
.В общем, лучше вообще не
null
быть там ... если только это неnull
имеет очень конкретного значения в вашем приложении или дизайне API. Таким образом, вместо того, чтобы избегать NPE с большим количеством защитного кодирования, лучше позволить NPE произойти, а затем отследить и исправить источник непредвиденногоnull
, вызвавшего NPE.Итак, как это применимо здесь?
Что ж, если вы думаете об этом, использование
String.valueOf(obj)
могло бы быть способом "исправления положения". Этого следует избегать. Если неожиданноobj
оказатьсяnull
в контексте, лучше использоватьobj.toString()
.источник
Большинство из них уже упоминалось в других ответах, но я просто добавляю его для полноты:
.toString()
как они не являются реализациейObject
класса -class, поэтомуString.valueOf
могут использоваться только.String.valueOf
преобразует данный объектnull
в String"null"
, тогда как.toString()
вызоветNullPointerException
.Компилятор будет использоватьРЕДАКТИРОВАТЬ: На самом деле он будет использоватьString.valueOf
по умолчанию, когда используется что-то вродеString s = "" + (...);
. Вот почему вObject t = null; String s = "" + t;
результате будет строка"null"
, а не NPE.StringBuilder.append
, а неString.valueOf
. Так что игнорируйте то, что я здесь сказал.В дополнение к этому, вот пример использования, когда
String.valueOf
и.toString()
имеют разные результаты:Допустим, у нас есть такой общий метод:
И мы будем называть его с
Integer
типом , как это:Main.<Integer>test()
.Когда мы создаем String,
String.valueOf
он отлично работает:Это будет выводиться
test
в STDOUT.Однако с a
.toString()
это не сработает:Это приведет к следующей ошибке:
Попробуйте онлайн.
Что касается почему, я могу сослаться на этот отдельный вопрос и ответы на него . Вкратце, однако:
.toString()
он сначала компилировать и оценивать объект, в котором приведение кT
(который являетсяString
кInteger
отлит в данном случае) приведет кClassCastException
.String.valueOf
он будет видеть общий файл,T
какObject
во время компиляции, и даже не заботится о том, чтобы он былInteger
. Таким образом, он будет приводитьObject
кObject
(что компилятор просто игнорирует). Затем он будет использоватьString.valueOf(Object)
, что приведет кString
ожидаемому результату. Таким образом, даже несмотря наString.valueOf(Object)
то,.toString()
что внутри параметра будет выполняться a , мы уже пропустили приведение и обработали его как anObject
, поэтому мы избежали того,ClassCastException
что происходит с использованием.toString()
.Просто подумал, что стоит упомянуть эту дополнительную разницу между
String.valueOf
и.toString()
здесь.источник
("" + x)
скомпилированное вString.valueOf(x)
, но для чего-то более сложного использовалсяStringBuffer
(тогда у нас не былоStringBuilder
).String.valueOf(Object)
иObject.toString()
буквально одно и то же.Если вы посмотрите на реализацию String.valueOf (Object) , вы увидите, что
String.valueOf(Object)
это в основном просто нулевой безопасный вызовtoString()
соответствующего объекта:источник
Наиболее важным отличием является способ обработки ссылок на пустые строки.
источник
Когда аргумент равен
null
,String.valueOf
возвращает"null"
, ноObject.toString
выбрасываетNullPointerException
, это единственная разница.источник
Есть еще одно важное различие между этими двумя методами: когда объект, который мы конвертируем, является массивом.
Когда вы конвертируете массив с помощью Object.toString (), вы получите какое-то значение мусора (@, за которым следует хэш-код массива).
Чтобы получить удобочитаемый toString (), вы должны использовать String.valueOf (char []); Пожалуйста, обратите внимание, что этот метод работает только для массива типа char. Я бы рекомендовал использовать Arrays.toString (Object []) для преобразования массивов в String.
Второе отличие заключается в том, что когда объект имеет значение NULL, ValueOf () возвращает String «null», а toString () возвращает исключение с нулевым указателем.
источник
Я не могу точно сказать, в чем разница, но кажется разница при работе на уровне байтов. В следующем сценарии шифрования Object.toString () выдал значение, которое не удалось расшифровать, тогда как String.valueOf () работал по назначению ...
источник
valueOf(char[])
а неvalueOf(Object)
. ПоведениеvalueOf(char[])
существенно отличается отchar[].toString()
. Но так или иначе, этот ответ не по поводу , потому что вы вызываете другую перегрузку в один Вопрос спрашивает о.И в большинстве случаев лучше возвращать NPE, чем "нулевое" значение.
источник
Ниже показана реализация java.lang.String.valueOf, как описано в исходном коде jdk8u25. Итак, согласно моему комментарию, разницы нет. Он вызывает Object.toString. Для примитивных типов он оборачивает его в объектную форму и вызывает для него «toString».
Увидеть ниже:
источник