在Java中,String.valueOf(Object)
和之间有什么区别Object.toString()
?是否有针对这些的特定代码约定?
null
首先检查。
在Java中,String.valueOf(Object)
和之间有什么区别Object.toString()
?是否有针对这些的特定代码约定?
null
首先检查。
Answers:
根据Java文档,String.valueOf()
返回:
如果参数是
null
,则字符串等于"null"
; 否则,obj.toString()
返回的值。
因此,除了附加的方法调用外,实际上没有什么区别。
另外,在的情况下Object#toString
,如果实例为null
,NullPointerException
则将抛出a,因此可以说,它的安全性较低。
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)
NPE。它仅适用于null的对象。
String.valueOf(null)
实际解析为valueOf(char[])
超载。这是因为char[]
是比更加具体的类型Object
。
String.valueOf(Object)和Object.toString()之间的区别是:
1) 如果string为null,
String.valueOf(Object)
将返回null
,而Object::toString()
将抛出空指针异常。
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)签名:
String类的valueOf()方法是静态的。而String类的toString()方法是非静态的。
字符串的valueOf()方法的签名或语法如下:
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)
字符串toString()
方法的签名或语法如下:
public String toString()
在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 = new char[]('a', 'b', 'c');
System.out.println(String.valueOf(abc)); // prints "abc"
System.out.println(abc.toString()); // prints "[C@...."
是否有针对这些的特定代码约定?
没有。
使用最适合您所使用的上下文的要求的方法。(您需要使用格式null
吗?)
注意:这不是代码约定。这只是常识编程。与遵循某种风格惯例或“最佳实践”教条相比,使您的代码正确更为重要。
个人观点:
一些开发人员习惯(IMO)抵制null的坏习惯。因此,您会看到很多针对null的测试,并将null视为特殊情况。这个想法似乎是在阻止NPE的发生。
我认为这是一个坏主意。尤其是,如果您发现a时所做的事情null
是试图“做得好” ...而不考虑为什么存在a的话,我认为这是一个坏主意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;
将导致String "null"
而不是NPE的原因。StringBuilder.append
不是String.valueOf
。因此,请忽略我在这里说的话。除了这些之外,这实际上是一个用例,其中String.valueOf
并.toString()
具有不同的结果:
假设我们有一个类似的通用方法:
public static <T> T test(){
String str = "test";
return (T) str;
}
我们用这样的Integer
类型来称呼它:Main.<Integer>test()
。
当我们使用String.valueOf
它创建一个String时,它可以正常工作:
String s1 = String.valueOf(Main.<Integer>test());
System.out.println(s1);
这将输出 test
到STDOUT。
.toString()
但是,使用a 无效:
String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);
这将导致以下错误:
java.lang.ClassCastException
:班级java.lang.String
不能转换为班级java.lang.Integer
至于为什么,我可以参考这个分离的问题及其答案。简而言之:
.toString()
,它将首先编译并评估对象,强制转换为T
(在这种情况下String
为Integer
强制转换)将导致ClassCastException
。String.valueOf
时会在编译期间看到泛型T
,Object
甚至不必担心它是一个Integer
。因此它将强制转换Object
为Object
(编译器将忽略)。然后将使用String.valueOf(Object)
,得到String
预期的结果。因此,即使String.valueOf(Object)
will .toString()
在内部对参数执行了操作,我们也已经跳过了强制转换并将其视为an Object
,因此我们避免了ClassCastException
使用时发生的.toString()
。只是认为值得一提的是String.valueOf
和之间还有这个额外的区别.toString()
。
("" + x)
编译到的String.valueOf(x)
,但是任何更复杂的事情都使用了StringBuffer
(StringBuilder
那时我们还没有)。
String.valueOf(Object)
和Object.toString()
实际上是同一件事。
如果看一下String.valueOf(Object)的实现,您会发现这String.valueOf(Object)
基本上只是toString()
对适当对象的null安全调用:
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();
}
最重要的区别是它们处理null字符串引用的方式。
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
两种方法之间的另一个主要区别是,当我们要转换的对象是数组时。
当使用Object.toString()转换数组时,您将获得某种垃圾值(@后跟数组的哈希码)。
要获取易于理解的toString(),必须使用String.valueOf(char []);。请注意,此方法仅适用于char类型的Array。我建议使用Arrays.toString(Object [])将数组转换为String。
第二个区别是,当对象为null时,ValueOf()返回字符串“ null”,而toString()将返回null指针异常。
我不能确切地说出区别是什么,但是在字节级别操作时似乎有所区别。在以下加密方案中,Object.toString()产生了一个无法解密的值,而String.valueOf()却按预期工作了……
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[])
而不是valueOf(Object)
。的行为与valueOf(char[])
明显不同char[].toString()
。但无论哪种方式,这个答案是不中肯的,因为要调用不同过载到一个问题的询问。
下面显示了jdk8u25的源代码中描述的java.lang.String.valueOf的实现。因此,根据我的评论,没有区别。它称为“ Object.toString”。对于基本类型,它将其包装为对象形式并在其上调用“ toString”。
见下文:
/*
* 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
被使用。对于覆盖toString的对象,我认为String.valueOf可能会调用它。虽然不确定那部分。