Los tipos primitivos no tienen un "toString" ... por lo que String.valueOfse usa. Para los objetos que anulan aString, creo que String.valueOf podría llamar a eso en su lugar. Aunque no estoy seguro de esa parte.
Brandon
@ Brandon Tienes razón, hace exactamente eso, excepto que comprueba nullprimero.
azurefrog
El primer comentario aquí creo que tiene más sentido si es correcto. Debe usar String.valueOf en ciertas situaciones en las que el objetivo es un tipo primitivo.
si el argumento es null, entonces una cadena igual a "null"; de lo contrario, obj.toString()se devuelve el valor de .
Por lo tanto, no debería haber una diferencia, excepto una invocación de método adicional.
Además, en el caso de Object#toString, si la instancia es null, se NullPointerExceptionlanzará un , por lo que podría decirse que es menos seguro .
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}
Esta es la mejor respuesta. Lea y confíe en los javadocs, no en el código. (El código en principio podría ser diferente para diferentes versiones / lanzamientos de Java.)
Stephen C
77
@ Brandon - Incorrecto. Solo necesita cambiar si el comportamiento cambia de una manera que invalida el javadoc. 1) Las posibilidades de que eso suceda para este método son CERO. No harán un cambio que justifique un cambio en la especificación, y si lo hicieran , cambiarían la especificación. 2) No invalida mi consejo. Si lees el javadoc, ¡verás que el comportamiento documentado ha cambiado!
Stephen C
2
¿No sería más seguro el método que arroja la excepción ? Por lo general, cuando su código arroja una NullPointerException, es algo bueno. Puede que no se sienta bien para el desarrollador en este momento ("aww, no, ahora tengo que volver y arreglar mi código"), pero como se produjo el error, descubriste que necesitabas arreglar algo. Si se deja al revés, está exponiendo el "nulo" directamente al usuario y no se informa un error a menos que lo compruebe explícitamente, lo que me parece menos seguro.
Tim M.
1
Para ser claros, en realidad no se puede llamar String.valueOf(null), eso es un NPE. Solo funciona para objetos que son nulos.
Noumenon
1
Esa no es la explicación. El String.valueOf(null)realmente resuelve la valueOf(char[])sobrecarga. Esto se debe a que char[]es un tipo más específico que Object.
Stephen C
17
Las diferencias entre String.valueOf (Object) y Object.toString () son:
1) Si la cadena es nula,
String.valueOf(Object)regresará null, mientras Object::toString()que lanzará una excepción de puntero nulo.
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) Firma:
El método valueOf () de la clase String es estático. mientras que el método toString () de la clase String no es estático.
La firma o sintaxis del método valueOf () de la cadena se proporciona a continuación:
En Java, ¿hay alguna diferencia entre String.valueOf (Object) y Object.toString ()?
Si. (¡Y más si consideras sobrecargar!)
Como explica el javadoc , String.valueOf((Object) null)se tratará como un caso especial por el valueOfmétodo y "null"se devolverá el valor . Por el contrario, null.toString()solo le dará un NPE.
Sobrecarga
Resulta que String.valueOf(null)(tenga en cuenta la diferencia!) Hace dar una NPE ... a pesar de la javadoc. La explicación es oscura:
Hay varias sobrecargas de String.valueOf, pero hay dos que son relevantes aquí: String.valueOf(Object)y String.valueOf(char[]).
En la expresión String.valueOf(null), ambas sobrecargas son aplicables , ya nullque la asignación es compatible con cualquier tipo de referencia.
Cuando hay dos o más sobrecargas aplicables , el JLS dice que se elige la sobrecarga para el tipo de argumento más específico .
Como char[]es un subtipo de Object, es más específico .
Por lo tanto, String.valueOf(char[])se llama la sobrecarga.
String.valueOf(char[])lanza un NPE si su argumento es una matriz nula. A diferencia String.valueOf(Object), no se trata nullcomo un caso especial.
(Puede confirmar esto usando javap -cpara examinar el código de un método que tiene una String.valueOf(null)llamada. Observe la sobrecarga que se usa para la llamada).
Otro ejemplo ilustra la diferencia en la valueOf(char[])sobrecarga aún más claramente:
char[] abc =newchar[]('a','b','c');System.out.println(String.valueOf(abc));// prints "abc"System.out.println(abc.toString());// prints "[C@...."
¿Existe una convención de código específica para estos?
No.
Utilice el que sea más apropiado para los requisitos del contexto en el que lo está utilizando. (¿ Necesita el formato para trabajar null?)
Nota: eso no es una convención de código. Es solo programación de sentido común. Es más importante que su código sea correcto que seguir alguna convención estilística o dogma de "mejores prácticas".
Opinión personal:
Algunos desarrolladores adquieren el mal hábito (IMO) de "defenderse" de los nulos. Entonces ve muchas pruebas de nulos y trata los nulos como casos especiales. La idea parece ser evitar que suceda NPE.
Creo que esta es una mala idea. En particular, creo que es una mala idea si lo que haces cuando encuentras un nulles tratar de "hacer el bien" ... sin tener en cuenta por qué había un nullallí.
En general, es mejor evitar nullestar allí en primer lugar ... a menos que nulltenga un significado muy específico en su aplicación o diseño de API. Entonces, en lugar de evitar el NPE con mucha codificación defensiva, es mejor dejar que ocurra el NPE, y luego rastrear y corregir la fuente de lo inesperado nullque desencadenó el NPE.
Entonces, ¿cómo se aplica esto aquí?
Bueno, si lo piensas bien, usar String.valueOf(obj)podría ser una forma de "hacer el bien". Eso debe ser evitado. Si es inesperado objestar nullen el contexto, es mejor usarlo obj.toString().
La mayoría ya ha sido mencionada por otras respuestas, pero solo la agrego para completar:
Las primitivas no tienen una, .toString()ya que no son una implementación de la Objectclase, por lo que solo String.valueOfse pueden usar.
String.valueOftransformará un objeto dado que está nullen la cadena "null", mientras .toString()que arrojará un NullPointerException.
El compilador lo usará String.valueOfpor defecto cuando se use algo así String s = "" + (...);. Es por eso Object t = null; String s = "" + t;que resultará en la Cadena "null", y no en un NPE. EDITAR: En realidad, usará el StringBuilder.append, no String.valueOf. Ignora lo que dije aquí.
Además de esos, aquí hay un caso de uso donde String.valueOfy .toString()tienen diferentes resultados:
Digamos que tenemos un método genérico como este:
publicstatic<T> T test(){String str ="test";return(T) str;}
Y lo vamos a llamar con un Integertipo como este: Main.<Integer>test().
Cuando creamos una cadena con String.valueOfella funciona bien:
Cuando se utiliza .toString()por primera vez compilará y evaluar el objeto, donde el elenco a T(que es una Stringde Integerfundido en este caso) dará lugar a la ClassCastException.
Al usarlo String.valueOfverá el genérico Tcomo Objectdurante la compilación y ni siquiera le importa que sea un Integer. Entonces lanzará un Objectto Object(que el compilador simplemente ignora). Luego lo usará String.valueOf(Object), dando Stringcomo resultado lo esperado. Entonces, a pesar de String.valueOf(Object)que hará un .toString()parámetro interno, ya hemos omitido el reparto y se lo trata como un Object, así que hemos evitado lo ClassCastExceptionque ocurre con el uso de .toString().
Solo pensé que valía la pena mencionar esta diferencia adicional entre String.valueOfy .toString()aquí también.
La última vez que me importó esto, que habría sido alrededor de JDK 1.2, ("" + x)compilado String.valueOf(x), pero cualquier cosa más complicada usaba un StringBuffer(no teníamos StringBuilderentonces).
Neil
4
String.valueOf(Object)y Object.toString()son literalmente lo mismo.
Si echa un vistazo a la implementación de String.valueOf (Object) , verá que String.valueOf(Object)es básicamente una invocación nula-segura del toString()objeto apropiado:
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();}
Hay una diferencia importante más entre los dos métodos es cuando el objeto que estamos convirtiendo es una matriz.
Cuando convierte una matriz usando Object.toString () obtendrá algún tipo de valor basura (@ seguido del código hash de la matriz).
Para obtener un toString () legible para humanos, debe usar String.valueOf (char []); tenga en cuenta que este método solo funciona para Array de tipo char. Recomendaría usar Arrays.toString (Object []) para convertir matrices a String.
La segunda diferencia es cuando el objeto es nulo, ValueOf () devuelve un String "nulo", mientras que toString () devolverá una excepción de puntero nulo.
Hola @Tom, esto es cierto para una matriz de cualquier tipo. Sin embargo, si está utilizando Arrays.toString (Object []), puede convertir una matriz de cualquier tipo a cadena.
chintan thakker
Hola, @Tom Object.toString () que devuelve un valor basura es verdadero para una matriz de cualquier tipo, tienes razón en que String.valueOf (Array) dará una cadena correcta solo para una matriz de tipo char. Debería haber mencionado que, gracias, lo editaré.
Chintan Thakker
1
Ese no es un valor basura, es el nombre de clase y el código hash ( JavaDoc ).
Tom
-1
No puedo decir exactamente cuál es la diferencia, pero parece haber una diferencia cuando se opera a nivel de byte. En el siguiente escenario de cifrado, Object.toString () produjo un valor que no se pudo descifrar, mientras que String.valueOf () funcionó según lo previsto ...
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()
La explicación es que en realidad estás llamando en valueOf(char[])lugar de valueOf(Object). El comportamiento de valueOf(char[])es significativamente diferente a char[].toString(). Pero de cualquier manera, esta respuesta no es apropiada porque está llamando a una sobrecarga diferente a la pregunta sobre la que pregunta.
Stephen C
-2
A continuación se muestra la implementación de java.lang.String.valueOf como se describe en la fuente de jdk8u25. Entonces, según mi comentario, no hay diferencia. Se llama "Object.toString". Para los tipos primitivos, lo envuelve en su forma de objeto y lo llama "toString".
Vea abajo:
/*
* 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
se usa. Para los objetos que anulan aString, creo que String.valueOf podría llamar a eso en su lugar. Aunque no estoy seguro de esa parte.null
primero.Respuestas:
De acuerdo con la documentación de Java ,
String.valueOf()
devuelve:Por lo tanto, no debería haber una diferencia, excepto una invocación de método adicional.
Además, en el caso de
Object#toString
, si la instancia esnull
, seNullPointerException
lanzará un , por lo que podría decirse que es menos seguro .fuente
String.valueOf(null)
, eso es un NPE. Solo funciona para objetos que son nulos.String.valueOf(null)
realmente resuelve lavalueOf(char[])
sobrecarga. Esto se debe a quechar[]
es un tipo más específico queObject
.Las diferencias entre String.valueOf (Object) y Object.toString () son:
1) Si la cadena es nula,
String.valueOf(Object)
regresaránull
, mientrasObject::toString()
que lanzará una excepción de puntero nulo.2) Firma:
El método valueOf () de la clase String es estático. mientras que el método toString () de la clase String no es estático.
La firma o sintaxis del método valueOf () de la cadena se proporciona a continuación:
La firma o sintaxis del
toString()
método de cadena se da a continuación:fuente
Si. (¡Y más si consideras sobrecargar!)
Como explica el javadoc ,
String.valueOf((Object) null)
se tratará como un caso especial por elvalueOf
método y"null"
se devolverá el valor . Por el contrario,null.toString()
solo le dará un NPE.Sobrecarga
Resulta que
String.valueOf(null)
(tenga en cuenta la diferencia!) Hace dar una NPE ... a pesar de la javadoc. La explicación es oscura:Hay varias sobrecargas de
String.valueOf
, pero hay dos que son relevantes aquí:String.valueOf(Object)
yString.valueOf(char[])
.En la expresión
String.valueOf(null)
, ambas sobrecargas son aplicables , yanull
que la asignación es compatible con cualquier tipo de referencia.Cuando hay dos o más sobrecargas aplicables , el JLS dice que se elige la sobrecarga para el tipo de argumento más específico .
Como
char[]
es un subtipo deObject
, es más específico .Por lo tanto,
String.valueOf(char[])
se llama la sobrecarga.String.valueOf(char[])
lanza un NPE si su argumento es una matriz nula. A diferenciaString.valueOf(Object)
, no se tratanull
como un caso especial.(Puede confirmar esto usando
javap -c
para examinar el código de un método que tiene unaString.valueOf(null)
llamada. Observe la sobrecarga que se usa para la llamada).Otro ejemplo ilustra la diferencia en la
valueOf(char[])
sobrecarga aún más claramente:No.
Utilice el que sea más apropiado para los requisitos del contexto en el que lo está utilizando. (¿ Necesita el formato para trabajar
null
?)Nota: eso no es una convención de código. Es solo programación de sentido común. Es más importante que su código sea correcto que seguir alguna convención estilística o dogma de "mejores prácticas".
Opinión personal:
Algunos desarrolladores adquieren el mal hábito (IMO) de "defenderse" de los nulos. Entonces ve muchas pruebas de nulos y trata los nulos como casos especiales. La idea parece ser evitar que suceda NPE.
Creo que esta es una mala idea. En particular, creo que es una mala idea si lo que haces cuando encuentras un
null
es tratar de "hacer el bien" ... sin tener en cuenta por qué había unnull
allí.En general, es mejor evitar
null
estar allí en primer lugar ... a menos quenull
tenga un significado muy específico en su aplicación o diseño de API. Entonces, en lugar de evitar el NPE con mucha codificación defensiva, es mejor dejar que ocurra el NPE, y luego rastrear y corregir la fuente de lo inesperadonull
que desencadenó el NPE.Entonces, ¿cómo se aplica esto aquí?
Bueno, si lo piensas bien, usar
String.valueOf(obj)
podría ser una forma de "hacer el bien". Eso debe ser evitado. Si es inesperadoobj
estarnull
en el contexto, es mejor usarloobj.toString()
.fuente
La mayoría ya ha sido mencionada por otras respuestas, pero solo la agrego para completar:
.toString()
ya que no son una implementación de laObject
clase, por lo que soloString.valueOf
se pueden usar.String.valueOf
transformará un objeto dado que estánull
en la cadena"null"
, mientras.toString()
que arrojará unNullPointerException
.El compilador lo usaráEDITAR: En realidad, usará elString.valueOf
por defecto cuando se use algo asíString s = "" + (...);
. Es por esoObject t = null; String s = "" + t;
que resultará en la Cadena"null"
, y no en un NPE.StringBuilder.append
, noString.valueOf
. Ignora lo que dije aquí.Además de esos, aquí hay un caso de uso donde
String.valueOf
y.toString()
tienen diferentes resultados:Digamos que tenemos un método genérico como este:
Y lo vamos a llamar con un
Integer
tipo como este:Main.<Integer>test()
.Cuando creamos una cadena con
String.valueOf
ella funciona bien:Esto dará salida
test
a STDOUT.Sin
.toString()
embargo, no funcionará:Esto dará como resultado el siguiente error:
Pruébalo en línea.
En cuanto a por qué, puedo referirme a esta pregunta separada y sus respuestas . En resumen, sin embargo:
.toString()
por primera vez compilará y evaluar el objeto, donde el elenco aT
(que es unaString
deInteger
fundido en este caso) dará lugar a laClassCastException
.String.valueOf
verá el genéricoT
comoObject
durante la compilación y ni siquiera le importa que sea unInteger
. Entonces lanzará unObject
toObject
(que el compilador simplemente ignora). Luego lo usaráString.valueOf(Object)
, dandoString
como resultado lo esperado. Entonces, a pesar deString.valueOf(Object)
que hará un.toString()
parámetro interno, ya hemos omitido el reparto y se lo trata como unObject
, así que hemos evitado loClassCastException
que ocurre con el uso de.toString()
.Solo pensé que valía la pena mencionar esta diferencia adicional entre
String.valueOf
y.toString()
aquí también.fuente
("" + x)
compiladoString.valueOf(x)
, pero cualquier cosa más complicada usaba unStringBuffer
(no teníamosStringBuilder
entonces).String.valueOf(Object)
yObject.toString()
son literalmente lo mismo.Si echa un vistazo a la implementación de String.valueOf (Object) , verá que
String.valueOf(Object)
es básicamente una invocación nula-segura deltoString()
objeto apropiado:fuente
La diferencia más importante es la forma en que manejan las referencias de cadena nulas.
fuente
Cuando el argumento es
null
, losString.valueOf
retornos"null"
, peroObject.toString
arrojaNullPointerException
, esa es la única diferencia.fuente
Hay una diferencia importante más entre los dos métodos es cuando el objeto que estamos convirtiendo es una matriz.
Cuando convierte una matriz usando Object.toString () obtendrá algún tipo de valor basura (@ seguido del código hash de la matriz).
Para obtener un toString () legible para humanos, debe usar String.valueOf (char []); tenga en cuenta que este método solo funciona para Array de tipo char. Recomendaría usar Arrays.toString (Object []) para convertir matrices a String.
La segunda diferencia es cuando el objeto es nulo, ValueOf () devuelve un String "nulo", mientras que toString () devolverá una excepción de puntero nulo.
fuente
No puedo decir exactamente cuál es la diferencia, pero parece haber una diferencia cuando se opera a nivel de byte. En el siguiente escenario de cifrado, Object.toString () produjo un valor que no se pudo descifrar, mientras que String.valueOf () funcionó según lo previsto ...
fuente
valueOf(char[])
lugar devalueOf(Object)
. El comportamiento devalueOf(char[])
es significativamente diferente achar[].toString()
. Pero de cualquier manera, esta respuesta no es apropiada porque está llamando a una sobrecarga diferente a la pregunta sobre la que pregunta.A continuación se muestra la implementación de java.lang.String.valueOf como se describe en la fuente de jdk8u25. Entonces, según mi comentario, no hay diferencia. Se llama "Object.toString". Para los tipos primitivos, lo envuelve en su forma de objeto y lo llama "toString".
Vea abajo:
fuente