Tipos primitivos não têm um "toString" .. então String.valueOfé usado. Para objetos que substituem toString, acho que String.valueOf pode chamar isso. Não tenho certeza sobre essa parte embora.
Brandon
@Brandon Você está correto, faz exatamente isso, exceto pelo fato de verificar nullprimeiro.
Azurefrog
Acho que o primeiro comentário aqui faz mais sentido se estiver correto. Você deve usar String.valueOf em determinadas situações em que o destino é um tipo primitivo.
se o argumento for null, uma sequência igual a "null"; caso contrário, o valor de obj.toString()é retornado.
Portanto, realmente não deve haver diferença, exceto por uma invocação de método adicional.
Além disso, no caso de Object#toString, se a instância for null, a NullPointerExceptionserá lançada, então, sem dúvida, é 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 é a melhor resposta. Leia e confie nos javadocs, não no código. (O código poderia, em princípio, ser diferente para diferentes versões / versões do Java.)
Stephen C
7
@Brandon - Incorreto. Ele só precisa mudar se o comportamento mudar de uma maneira que invalide o javadoc. 1) As chances de isso acontecer para este método são ZERO. Eles não vão fazer uma mudança que justifique uma mudança na especificação, e se eles fizeram, então eles iria mudar o spec. 2) Não invalida meu conselho. Se você ler o javadoc, verá que o comportamento documentado mudou!
Stephen C
2
O método que lança a exceção não seria mais seguro? Normalmente, quando seu código lança uma NullPointerException, é uma coisa boa. Pode não parecer bom para o desenvolvedor no momento ("aww, não, agora preciso voltar e corrigir meu código"), mas desde que o erro foi lançado, você descobriu que precisava corrigir algo. De outra maneira, você está expondo o "nulo" diretamente ao usuário e não está recebendo um erro relatado, a menos que verifique explicitamente um, o que me parece menos seguro.
Tim M.
1
Só para deixar claro, você não pode ligar de verdade String.valueOf(null), isso é um NPE. Funciona apenas para objetos que são nulos.
Noumenon
1
Essa não é a explicação. O String.valueOf(null)realmente resolve a valueOf(char[])sobrecarga. Isso ocorre porque char[]é um tipo mais específico que Object.
Stephen C
17
As diferenças entre String.valueOf (Object) e Object.toString () são:
1) Se a string for nula,
String.valueOf(Object)retornará null, enquanto Object::toString()lançará uma exceção de ponteiro 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) Assinatura:
O método valueOf () da classe String é estático. enquanto o método toString () da classe String não é estático.
A assinatura ou sintaxe do método valueOf () da string é fornecida abaixo:
Em Java, existe alguma diferença entre String.valueOf (Object) e Object.toString ()?
Sim. (E mais ainda, se você considerar sobrecarregar!)
Como o javadoc explica, String.valueOf((Object) null)será tratado como um caso especial pelo valueOfmétodo e o valor "null"será retornado. Por outro lado, null.toString()apenas fornecerá um NPE.
Sobrecarga
Acontece que String.valueOf(null)(note a diferença!) Faz dar um NPE ... apesar do javadoc. A explicação é obscura:
Há várias sobrecargas de String.valueOf, mas há duas que são relevantes aqui: String.valueOf(Object)e String.valueOf(char[]).
Na expressão String.valueOf(null), essas duas sobrecargas são aplicáveis , pois nullé uma atribuição compatível com qualquer tipo de referência.
Quando há duas ou mais sobrecargas aplicáveis , o JLS diz que a sobrecarga para o tipo de argumento mais específico é escolhida.
Como char[]é um subtipo de Object, é mais específico .
Portanto, a String.valueOf(char[])sobrecarga é chamada.
String.valueOf(char[])lança um NPE se seu argumento for uma matriz nula. Ao contrário String.valueOf(Object), não trata nullcomo um caso especial.
(Você pode confirmar isso usando javap -cpara examinar o código de um método que possui uma String.valueOf(null)chamada. Observe a sobrecarga usada na chamada.)
Outro exemplo ilustra a diferença na valueOf(char[])sobrecarga ainda mais claramente:
char[] abc =newchar[]('a','b','c');System.out.println(String.valueOf(abc));// prints "abc"System.out.println(abc.toString());// prints "[C@...."
Existe uma convenção de código específica para eles?
Não.
Use o que for mais adequado aos requisitos do contexto em que você o está usando. (Você precisa da formatação para trabalhar null?)
Nota: isso não é uma convenção de código. É apenas programação de senso comum. É mais importante que seu código esteja correto do que seguir algumas convenções estilísticas ou dogmas de "melhores práticas".
Opinião pessoal:
Alguns desenvolvedores adquirem o mau hábito (IMO) de "defender" contra nulos. Então você vê muitos testes para nulos e trata os nulos como casos especiais. A idéia parece impedir que o NPE aconteça.
Acho que é uma má idéia. Em particular, acho que é uma má idéia se o que você faz quando encontra um nullé tentar "fazer o bem" ... sem considerar o porquê de haver um nulllá.
Em geral, é melhor evitar nullestar lá em primeiro lugar ... a menos que isso nulltenha um significado muito específico no seu aplicativo ou no design da API. Portanto, em vez de evitar o NPE com muita codificação defensiva, é melhor deixar o NPE acontecer e, em seguida, rastrear e corrigir a fonte do inesperado nullque acionou o NPE.
Então, como isso se aplica aqui?
Bem, se você pensar bem, usar String.valueOf(obj)pode ser uma maneira de "melhorar". Isso deve ser evitado. Se for inesperado objestar nullno contexto, é melhor usar obj.toString().
A maioria já foi mencionada por outras respostas, mas apenas a adiciono para completar:
As primitivas não têm uma, .toString()pois não são uma implementação da Objectclasse-, portanto, apenasString.valueOf podem ser usadas.
String.valueOftransformará um determinado objeto que é nulla String "null", enquanto .toString()lançará umNullPointerException .
O compilador usará String.valueOfpor padrão quando algo como String s = "" + (...);for usado. É por isso Object t = null; String s = "" + t;que resultará na String "null", e não em um NPE. EDIT: Na verdade, ele vai usar o StringBuilder.append, nãoString.valueOf . Então ignore o que eu disse aqui.
Além desses, aqui está realmente um caso de uso em que String.valueOfe.toString() obtém resultados diferentes:
Digamos que temos um método genérico como este:
publicstatic<T> T test(){String str ="test";return(T) str;}
E nós vamos chamá-lo com um Integertipo como este:Main.<Integer>test() .
Quando criamos uma String, String.valueOfela funciona bem:
Ao utilizar .toString()-lo em primeiro lugar reunir e avaliar o objecto, em que o fundido a T(que é uma Stringde Integerfundido neste caso) irá resultar naClassCastException .
Ao usá- String.valueOflo, ele verá o genérico Tcomo Objectdurante a compilação e nem se importa com isso Integer. Portanto, ele converterá um Objectpara Object(que o compilador simplesmente ignora). Em seguida, ele será usado String.valueOf(Object), resultando em um Stringcomo esperado. Assim, mesmo que o String.valueOf(Object)vai fazer um .toString()sobre o parâmetro internamente, nós já pulou o elenco e sua tratado como um Object, então temos evitado o ClassCastExceptionque ocorre com o uso de .toString().
Apenas pensei que valia a pena mencionar essa diferença adicional entre String.valueOfe .toString()aqui também.
A última vez que me importei com isso, que teria sido em torno do JDK 1.2, ("" + x)compilado String.valueOf(x), mas qualquer coisa mais complicada usou um StringBuffer(não tínhamos StringBuilderentão).
Neil
4
String.valueOf(Object)e Object.toString()são literalmente a mesma coisa.
Se você der uma olhada na implementação de String.valueOf (Object) , verá que String.valueOf(Object)é basicamente apenas uma invocação com segurança nula detoString() do objeto apropriado:
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();}
Há mais uma grande diferença entre os dois métodos: quando o objeto que estamos convertendo é uma matriz.
Ao converter uma matriz usando Object.toString (), você obtém algum tipo de valor de lixo (@ seguido pelo código de hash da matriz).
Para obter um toString () legível por humanos, você deve usar String.valueOf (char []); Por favor note que este método funciona apenas para Array do tipo char. Eu recomendaria usar Arrays.toString (Object []) para converter matrizes em String.
A segunda diferença é quando o objeto é nulo, ValueOf () retorna uma String "null", enquanto toString () retorna uma exceção de ponteiro nulo.
Oi @ Tom, isso é verdade para uma matriz de qualquer tipo. No entanto, se você estiver usando Arrays.toString (Object []), poderá converter uma matriz de qualquer tipo em string.
Thakker Chintan
Oi @ Tom Object.toString () retornando um valor de lixo é verdadeiro para uma matriz de qualquer tipo, você está certo de que String.valueOf (Array) fornecerá uma string correta apenas para uma matriz do tipo char. Eu deveria ter mencionado que, obrigado, vou editá-lo.
você precisa saber é o seguinte
1
Esse não é um valor de lixo, é o nome da classe e o código de hash ( JavaDoc ).
Tom
-1
Não sei dizer exatamente qual é a diferença, mas parece haver uma diferença ao operar no nível de bytes. No cenário de criptografia a seguir, Object.toString () produziu um valor que não pôde ser descriptografado, enquanto String.valueOf () funcionou conforme o esperado ...
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()
A explicação é que você está realmente ligando em valueOf(char[])vez de valueOf(Object). O comportamento de valueOf(char[])é significativamente diferente de char[].toString(). De qualquer forma, essa resposta não é adequada, porque você está chamando uma sobrecarga diferente daquela sobre a qual a pergunta é feita.
Stephen C
-2
A seguir, mostra a implementação do java.lang.String.valueOf, conforme descrito na fonte do jdk8u25. Então, de acordo com o meu comentário, não há diferença. Ele chama "Object.toString". Para tipos primitivos, ele o agrupa em sua forma de objeto e chama "toString" nele.
Ver abaixo:
/*
* 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
é usado. Para objetos que substituem toString, acho que String.valueOf pode chamar isso. Não tenho certeza sobre essa parte embora.null
primeiro.Respostas:
De acordo com a documentação Java ,
String.valueOf()
retorna:Portanto, realmente não deve haver diferença, exceto por uma invocação de método adicional.
Além disso, no caso de
Object#toString
, se a instância fornull
, aNullPointerException
será lançada, então, sem dúvida, é menos seguro .fonte
String.valueOf(null)
, isso é um NPE. Funciona apenas para objetos que são nulos.String.valueOf(null)
realmente resolve avalueOf(char[])
sobrecarga. Isso ocorre porquechar[]
é um tipo mais específico queObject
.As diferenças entre String.valueOf (Object) e Object.toString () são:
1) Se a string for nula,
String.valueOf(Object)
retornaránull
, enquantoObject::toString()
lançará uma exceção de ponteiro nulo.2) Assinatura:
O método valueOf () da classe String é estático. enquanto o método toString () da classe String não é estático.
A assinatura ou sintaxe do método valueOf () da string é fornecida abaixo:
A assinatura ou sintaxe do
toString()
método da string é fornecida abaixo:fonte
Sim. (E mais ainda, se você considerar sobrecarregar!)
Como o javadoc explica,
String.valueOf((Object) null)
será tratado como um caso especial pelovalueOf
método e o valor"null"
será retornado. Por outro lado,null.toString()
apenas fornecerá um NPE.Sobrecarga
Acontece que
String.valueOf(null)
(note a diferença!) Faz dar um NPE ... apesar do javadoc. A explicação é obscura:Há várias sobrecargas de
String.valueOf
, mas há duas que são relevantes aqui:String.valueOf(Object)
eString.valueOf(char[])
.Na expressão
String.valueOf(null)
, essas duas sobrecargas são aplicáveis , poisnull
é uma atribuição compatível com qualquer tipo de referência.Quando há duas ou mais sobrecargas aplicáveis , o JLS diz que a sobrecarga para o tipo de argumento mais específico é escolhida.
Como
char[]
é um subtipo deObject
, é mais específico .Portanto, a
String.valueOf(char[])
sobrecarga é chamada.String.valueOf(char[])
lança um NPE se seu argumento for uma matriz nula. Ao contrárioString.valueOf(Object)
, não tratanull
como um caso especial.(Você pode confirmar isso usando
javap -c
para examinar o código de um método que possui umaString.valueOf(null)
chamada. Observe a sobrecarga usada na chamada.)Outro exemplo ilustra a diferença na
valueOf(char[])
sobrecarga ainda mais claramente:Não.
Use o que for mais adequado aos requisitos do contexto em que você o está usando. (Você precisa da formatação para trabalhar
null
?)Nota: isso não é uma convenção de código. É apenas programação de senso comum. É mais importante que seu código esteja correto do que seguir algumas convenções estilísticas ou dogmas de "melhores práticas".
Opinião pessoal:
Alguns desenvolvedores adquirem o mau hábito (IMO) de "defender" contra nulos. Então você vê muitos testes para nulos e trata os nulos como casos especiais. A idéia parece impedir que o NPE aconteça.
Acho que é uma má idéia. Em particular, acho que é uma má idéia se o que você faz quando encontra um
null
é tentar "fazer o bem" ... sem considerar o porquê de haver umnull
lá.Em geral, é melhor evitar
null
estar lá em primeiro lugar ... a menos que issonull
tenha um significado muito específico no seu aplicativo ou no design da API. Portanto, em vez de evitar o NPE com muita codificação defensiva, é melhor deixar o NPE acontecer e, em seguida, rastrear e corrigir a fonte do inesperadonull
que acionou o NPE.Então, como isso se aplica aqui?
Bem, se você pensar bem, usar
String.valueOf(obj)
pode ser uma maneira de "melhorar". Isso deve ser evitado. Se for inesperadoobj
estarnull
no contexto, é melhor usarobj.toString()
.fonte
A maioria já foi mencionada por outras respostas, mas apenas a adiciono para completar:
.toString()
pois não são uma implementação daObject
classe-, portanto, apenasString.valueOf
podem ser usadas.String.valueOf
transformará um determinado objeto que énull
a String"null"
, enquanto.toString()
lançará umNullPointerException
.O compilador usaráEDIT: Na verdade, ele vai usar oString.valueOf
por padrão quando algo comoString s = "" + (...);
for usado. É por issoObject t = null; String s = "" + t;
que resultará na String"null"
, e não em um NPE.StringBuilder.append
, nãoString.valueOf
. Então ignore o que eu disse aqui.Além desses, aqui está realmente um caso de uso em que
String.valueOf
e.toString()
obtém resultados diferentes:Digamos que temos um método genérico como este:
E nós vamos chamá-lo com um
Integer
tipo como este:Main.<Integer>test()
.Quando criamos uma String,
String.valueOf
ela funciona bem:Isso resultará
test
em STDOUT.No
.toString()
entanto, com um não funcionará:Isso resultará no seguinte erro:
Experimente online.
Quanto ao porquê, posso me referir a essa pergunta separada e suas respostas . Em suma, no entanto:
.toString()
-lo em primeiro lugar reunir e avaliar o objecto, em que o fundido aT
(que é umaString
deInteger
fundido neste caso) irá resultar naClassCastException
.String.valueOf
lo, ele verá o genéricoT
comoObject
durante a compilação e nem se importa com issoInteger
. Portanto, ele converterá umObject
paraObject
(que o compilador simplesmente ignora). Em seguida, ele será usadoString.valueOf(Object)
, resultando em umString
como esperado. Assim, mesmo que oString.valueOf(Object)
vai fazer um.toString()
sobre o parâmetro internamente, nós já pulou o elenco e sua tratado como umObject
, então temos evitado oClassCastException
que ocorre com o uso de.toString()
.Apenas pensei que valia a pena mencionar essa diferença adicional entre
String.valueOf
e.toString()
aqui também.fonte
("" + x)
compiladoString.valueOf(x)
, mas qualquer coisa mais complicada usou umStringBuffer
(não tínhamosStringBuilder
então).String.valueOf(Object)
eObject.toString()
são literalmente a mesma coisa.Se você der uma olhada na implementação de String.valueOf (Object) , verá que
String.valueOf(Object)
é basicamente apenas uma invocação com segurança nula detoString()
do objeto apropriado:fonte
A diferença mais importante é a maneira como eles lidam com referências nulas de String.
fonte
Quando argumento é
null
, osString.valueOf
retornos"null"
, masObject.toString
lançaNullPointerException
, essa é a única diferença.fonte
Há mais uma grande diferença entre os dois métodos: quando o objeto que estamos convertendo é uma matriz.
Ao converter uma matriz usando Object.toString (), você obtém algum tipo de valor de lixo (@ seguido pelo código de hash da matriz).
Para obter um toString () legível por humanos, você deve usar String.valueOf (char []); Por favor note que este método funciona apenas para Array do tipo char. Eu recomendaria usar Arrays.toString (Object []) para converter matrizes em String.
A segunda diferença é quando o objeto é nulo, ValueOf () retorna uma String "null", enquanto toString () retorna uma exceção de ponteiro nulo.
fonte
Não sei dizer exatamente qual é a diferença, mas parece haver uma diferença ao operar no nível de bytes. No cenário de criptografia a seguir, Object.toString () produziu um valor que não pôde ser descriptografado, enquanto String.valueOf () funcionou conforme o esperado ...
fonte
valueOf(char[])
vez devalueOf(Object)
. O comportamento devalueOf(char[])
é significativamente diferente dechar[].toString()
. De qualquer forma, essa resposta não é adequada, porque você está chamando uma sobrecarga diferente daquela sobre a qual a pergunta é feita.A seguir, mostra a implementação do java.lang.String.valueOf, conforme descrito na fonte do jdk8u25. Então, de acordo com o meu comentário, não há diferença. Ele chama "Object.toString". Para tipos primitivos, ele o agrupa em sua forma de objeto e chama "toString" nele.
Ver abaixo:
fonte