String.valueOf()与Object.toString()


132

在Java中,String.valueOf(Object)和之间有什么区别Object.toString()?是否有针对这些的特定代码约定?


10
基本类型没有“ toString” ..因此String.valueOf被使用。对于覆盖toString的对象,我认为String.valueOf可能会调用它。虽然不确定那部分。
布兰登2014年

@Brandon你是正确的,它确实做到了,除了它null首先检查。
azurefrog 2014年

我认为这里的第一个评论最正确。在某些情况下,如果目标是原始类型,则必须使用String.valueOf。
多纳托

Answers:


177

根据Java文档String.valueOf()返回:

如果参数是null,则字符串等于"null"; 否则,obj.toString()返回的值。

因此,除了附加的方法调用外,实际上没有什么区别。

另外,在的情况下Object#toString,如果实例为nullNullPointerException则将抛出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
} 

6
这是最好的答案。阅读并依赖于javadocs,而不是代码。(原则上,对于不同版本的Java,代码可能会有所不同。)
Stephen C

7
@Brandon-不正确。仅当行为以使Javadoc无效的方式更改时,才需要更改。1)这种方法发生的可能性为零。他们不会做出需要更改规格的更改,而如果这样做,他们更改规格。2)这不会使我的建议无效。如果您阅读了Javadoc,那么您将看到记录的行为已更改!
斯蒂芬·C

2
引发异常的方法会安全吗?通常,当您的代码引发NullPointerException时,这是一件好事。暂时对开发人员来说感觉不太好(“ aww,不,现在我需要返回并修复我的代码”),但是由于抛出了错误,因此您发现需要修复某些内容。否则,您将“ null”直接暴露给用户,除非您明确检查一个,否则不会收到错误报告,这对我来说似乎不太安全。
蒂姆M.18年

1
需要说明的是,您实际上不能打电话给String.valueOf(null)NPE。它仅适用于null的对象。
Noumenon

1
那不是解释。在String.valueOf(null)实际解析为valueOf(char[])超载。这是因为char[]是比更加具体的类型Object
斯蒂芬C,

17

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()

13

在Java中,String.valueOf(Object)和Object.toString()之间有什么区别吗?

是。(还有更多,如果您考虑超载!)

作为Javadoc中解释的那样,String.valueOf((Object) null)将被视为由一种特殊情况valueOf的方法和值"null"被返回。相比之下,null.toString()只会给您NPE。

超载

事实证明String.valueOf(null)(注意区别!)确实给出了NPE ...尽管使用了javadoc。解释不清楚:

  1. 有许多重载String.valueOf,但这里有两个重载:String.valueOf(Object)String.valueOf(char[])

  2. 在表达式中String.valueOf(null),这两个重载均适用,因为null赋值与任何引用类型都兼容。

  3. 当有两个或多个适用的重载时,JLS表示已针对最特定的参数类型选择了重载。

  4. 由于char[]是的子类型Object,因此更为具体

  5. 因此,String.valueOf(char[])调用了过载。

  6. 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) 可能是一种“变好”的方式。这是要避免的。如果是意外的objnull在上下文,这是更好地使用obj.toString()


5

其他答案已经提到了大多数,但是为了完整起见,我仅添加了它:

  1. 基元没有-class,.toString()因为它们不是Object-class 的实现,因此只能String.valueOf使用。
  2. String.valueOf将转换为nullString 的给定对象"null",而.toString()将抛出NullPointerException
  3. 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(在这种情况下StringInteger强制转换)将导致ClassCastException
  • 使用String.valueOf时会在编译期间看到泛型TObject甚至不必担心它是一个Integer。因此它将强制转换ObjectObject(编译器将忽略)。然后将使用String.valueOf(Object),得到String预期的结果。因此,即使String.valueOf(Object)will .toString()在内部对参数执行了操作,我们也已经跳过了强制转换并将其视为an Object,因此我们避免了ClassCastException使用时发生的.toString()

只是认为值得一提的是String.valueOf和之间还有这个额外的区别.toString()


我上一次关心这个问题的时候,它本来是围绕JDK 1.2 ("" + x)编译到的String.valueOf(x),但是任何更复杂的事情都使用了StringBufferStringBuilder那时我们还没有)。
尼尔

4

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();
}

不正确,在char数组上同时使用valueOf和toString并大饱眼福。
Artanis '18

3

最重要的区别是它们处理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

1

当说法是null,该String.valueOf收益"null",但Object.toString抛出NullPointerException,这是唯一的区别。


0

两种方法之间的另一个主要区别是,当我们要转换的对象是数组时。

当使用Object.toString()转换数组时,您将获得某种垃圾值(@后跟数组的哈希码)。

要获取易于理解的toString(),必须使用String.valueOf(char []);。请注意,此方法仅适用于char类型的Array。我建议使用Arrays.toString(Object [])将数组转换为String。

第二个区别是,当对象为null时,ValueOf()返回字符串“ null”,而toString()将返回null指针异常。


@Tom,您好,对于任何类型的数组都是如此,但是,如果您使用Arrays.toString(Object []),则可以将任何类型的数组转换为字符串。
chintan thakker

嗨,@Tom Object.toString()返回垃圾值对于任何类型的数组都是正确的,您是正确的,String.valueOf(Array)仅会为char类型的数组提供正确的字符串。我应该提到,谢谢,我将对其进行编辑。
chintan thakker

1
那不是垃圾值,而是类名和哈希码(JavaDoc)。
汤姆

-1

我不能确切地说出区别是什么,但是在字节级别操作时似乎有所区别。在以下加密方案中,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()

为什么失败了?有什么问题?
Yousha Aleayoub

原因是您实际上在打电话valueOf(char[])而不是valueOf(Object)。的行为与valueOf(char[])明显不同char[].toString()。但无论哪种方式,这个答案是不中肯的,因为要调用不同过载到一个问题的询问。
Stephen C

-2

下面显示了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);
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.