Em Java, existe alguma diferença entre String.valueOf(Object)e Object.toString()? Existe uma convenção de código específica para eles?
nullprimeiro.
Em Java, existe alguma diferença entre String.valueOf(Object)e Object.toString()? Existe uma convenção de código específica para eles?
nullprimeiro.
Respostas:
De acordo com a documentação Java , String.valueOf()retorna:
se o argumento for
null, uma sequência igual a"null"; caso contrário, o valor deobj.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 .
public static void 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
}
String.valueOf(null), isso é um NPE. Funciona apenas para objetos que são nulos.
String.valueOf(null)realmente resolve a valueOf(char[])sobrecarga. Isso ocorre porque char[]é um tipo mais específico que Object.
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.
public static void 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:
public static String valueOf(boolean b)
public static String valueOf(char c)
public static String valueOf(char[] c)
public static String valueOf(int i)
public static String valueOf(long l)
public static String valueOf(float f)
public static String valueOf(double d)
public static String valueOf(Object o)
A assinatura ou sintaxe do toString()método da string é fornecida abaixo:
public String toString()
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.
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 = new char[]('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:
.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 .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. 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:
public static <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:
String s1 = String.valueOf(Main.<Integer>test());
System.out.println(s1);
Isso resultará testem STDOUT.
No .toString()entanto, com um não funcionará:
String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);
Isso resultará no seguinte erro:
java.lang.ClassCastException: classejava.lang.Stringnão pode ser convertida em classejava.lang.Integer
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 a T(que é uma Stringde Integerfundido neste caso) irá resultar naClassCastException .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.
("" + x)compilado String.valueOf(x), mas qualquer coisa mais complicada usou um StringBuffer(não tínhamos StringBuilderentão).
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()
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
A diferença mais importante é a maneira como eles lidam com referências nulas de String.
String str = null;
System.out.println("String.valueOf gives : " + String.valueOf(str));//Prints null
System.out.println("String.toString gives : " + str.toString());//This would throw a NullPointerExeption
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.
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 ...
private static char[] base64Encode(byte[] bytes)
{
return Base64.encode(bytes);
}
private static String encrypt(String encrypt_this) throws GeneralSecurityException, UnsupportedEncodingException
{
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
//THIS FAILED when attempting to decrypt the password
//return base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))).toString();
//THIS WORKED
return String.valueOf(base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))));
}//end of encrypt()
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.
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.
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
public static String valueOf(char data[]) {
return new String(data);
}
public static String valueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}
public static String copyValueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}
public static String copyValueOf(char data[]) {
return new String(data);
}
public static String valueOf(boolean b) {
return b ? "true" : "false";
}
public static String valueOf(char c) {
char data[] = {c};
return new String(data, true);
}
public static String valueOf(int i) {
return Integer.toString(i);
}
public static String valueOf(long l) {
return Long.toString(l);
}
public static String valueOf(float f) {
return Float.toString(f);
}
public static String valueOf(double d) {
return Double.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.