Java String.valueOf() 与 Object.toString()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27465731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:25:29  来源:igfitidea点击:

String.valueOf() vs. Object.toString()

javastring

提问by MCMastery

In Java, is there any difference between String.valueOf(Object)and Object.toString()? Is there a specific code convention for these?

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

采纳答案by Kuba Rakoczy

According to the Java documentation, String.valueOf()returns:

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

if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString()is returned.

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

So there shouldn't really be a difference except for an additional method invocation.

因此,除了额外的方法调用之外,应该没有真正的区别。

Also, in the case of Object#toString, if the instance is null, a NullPointerExceptionwill be thrown, so arguably, it's less safe.

此外,在 的情况下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
} 

回答by azurefrog

String.valueOf(Object)and Object.toString()are literally the same thing.

String.valueOf(Object)并且Object.toString()实际上是一回事。

If you take a look at the implementation of String.valueOf(Object), you'll see that String.valueOf(Object)is basically just a null-safe invocation of toString()of the appropriate object:

如果您查看String.valueOf(Object)的实现,您会发现它String.valueOf(Object)基本上只是toString()对适当对象的空安全调用:

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

回答by Brandon

The below shows the implementation for java.lang.String.valueOf as described in the source for jdk8u25. So as per my comment, there's no difference. It calls "Object.toString". For primitive types, it wraps it in its object form and calls "toString" on it.

下面显示了 jdk8u25 源代码中描述的 java.lang.String.valueOf 的实现。所以根据我的评论,没有区别。它调用“Object.toString”。对于原始类型,它将其包装在其对象形式中并在其上调用“toString”。

See below:

见下文:

/*
 * 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 Everv0id

When argument is null, the String.valueOfreturns "null", but Object.toStringthrows NullPointerException, that's the only difference.

当参数为 时nullString.valueOf返回"null",但Object.toString抛出NullPointerException,这是唯一的区别。

回答by Stephen C

In Java, is there any difference between String.valueOf(Object) and Object.toString()?

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

Yes. (And more so if you consider overloading!)

是的。(如果您考虑超载,则更是如此!)

As the javadocexplains, String.valueOf((Object) null)will be treated as a special case by the valueOfmethod and the value "null"is returned. By contrast, null.toString()will just give you an NPE.

正如javadoc 所解释的,String.valueOf((Object) null)将被方法视为特殊情况valueOf"null"返回值。相比之下,null.toString()只会给你一个 NPE。

Overloading

超载

It turns out that String.valueOf(null)(note the difference!) doesgive an NPE ... despite the javadoc. The explanation is obscure:

事实证明String.valueOf(null)(注意区别!)确实给了一个 NPE ......尽管有 javadoc。解释很模糊:

  1. There are a number of overloads of String.valueOf, but there are two that are relevant here: String.valueOf(Object)and String.valueOf(char[]).

  2. In the expression String.valueOf(null), both of those overloads are applicable, since nullis assignment compatible with any reference type.

  3. When there are two or more applicableoverloads, the JLS says that the overload for the most specificargument type is chosen.

  4. Since char[]is a subtype of Object, it is more specific.

  5. Therefore the String.valueOf(char[])overload is called.

  6. String.valueOf(char[])throws an NPE if its argument is a null array. Unlike String.valueOf(Object), it doesn't treat nullas a special case.

  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视为特殊情况。

(You can confirm this by using javap -cto examine the code of a method that has a String.valueOf(null)call. Observe the overload that is used for the call.)

(您可以通过使用javap -c检查具有String.valueOf(null)调用的方法的代码来确认这一点。观察用于调用的重载。)

Another example illustrates the difference in the valueOf(char[])overload even more clearly:

另一个例子valueOf(char[])更清楚地说明了重载的差异:

char[] abc = new char[]('a', 'b', 'c');
System.out.println(String.valueOf(abc));  // prints "abc"
System.out.println(abc.toString());       // prints "[C@...."


Is there a specific code convention for these?

这些是否有特定的代码约定?

No.

不。

Use which ever is most appropriate to the requirements of the context in which you are using it. (Do you needthe formatting to work for null?)

使用最适合您使用它的上下文的要求。(您需要格式化才能工作null吗?)

Note: that isn't a code convention. It is just common sense programming. It is more important that your code is correctthan it is to follow some stylistic convention or "best practice" dogma.

注意:这不是代码约定。这只是常识性编程。与遵循某种风格约定或“最佳实践”教条相比,您的代码正确更重要。



Personal opinion:

个人意见:

Some developers acquire the (IMO) bad habit of "defending" against nulls. So you see lots of tests for nulls, and treating nulls as special cases. The idea seems to be prevent NPE from happening.

一些开发人员养成了“防御”空值的 (IMO) 坏习惯。因此,您会看到许多针对空值的测试,并将空值视为特殊情况。这个想法似乎是为了防止 NPE 发生。

I think this is a bad idea. In particular, I think it is a bad idea if what you do when you find a nullis to try to "make good" ... without consideration of why there was a nullthere.

我认为这是一个坏主意。特别是,我认为如果您在找到 a 时所做的事情null是试图“做好”……而不考虑为什么存在 a null,那是个坏主意。

In general, it is better to avoid the nullbeing there in the first place ... unless the nullhas a very specific meaning in your application or API design. So, rather than avoiding the NPE with lots of defensive coding, it is better to let the NPE happen, and then track down and fix the source of the unexpected nullthat triggered the NPE.

一般来说,最好首先避免null存在……除非它null在您的应用程序或 API 设计中具有非常具体的含义。因此,与其避免使用大量防御性编码的 NPE,不如让 NPE 发生,然后追踪并修复null触发 NPE的意外来源。

So how does this apply here?

那么这如何适用于这里呢?

Well, if you think about it, using String.valueOf(obj)couldbe a way of "making good". That is to be avoided. If it is unexpected for objto be nullin the context, it is better to use obj.toString().

好吧,如果你仔细想想,使用String.valueOf(obj)可能是一种“做好”的方式。这是要避免的。如果是意外的objnull在上下文,这是更好地使用obj.toString()

回答by Abdullah Khan

The most important difference is the way they handle null String references.

最重要的区别是它们处理空字符串引用的方式。

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

回答by Chris Walters

I can't say exactly what the difference is but there appears to be a difference when operating at the byte level. In the following encryption scenario Object.toString() produced a value that couldn't be decrypted whereas String.valueOf() worked as intended ...

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

回答by Shipra Sharma

Differences between String.valueOf(Object) and Object.toString() are:

String.valueOf(Object) 和 Object.toString() 之间的区别是:

1)If string is null,

1)如果字符串为空,

String.valueOf(Object)will return null, whereas Object::toString()will throw a null pointer exception.

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) Signature:

2) 签名:

valueOf() method of String class is static. whereas toString() method of String class is non static.

String 类的 valueOf() 方法是静态的。而 String 类的 toString() 方法是非静态的。

The signature or syntax of string's valueOf() method is given below:

string 的 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)

The signature or syntax of string's toString()method is given below:

字符串toString()方法的签名或语法如下:

public String toString()

回答by chintan thakker

There is one more major difference between the two methods is when the object we are converting is an array.

这两种方法还有一个主要区别是我们转换的对象是数组。

When you convert an array using Object.toString() you will get some kind of garbage value(@ followed by hashcode of array).

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

To get a human-readable toString(), you must use String.valueOf(char[]); plz note that this method works only for Array of type char. I would recommend using Arrays.toString(Object[]) for converting arrays to String.

要获得人类可读的 toString(),您必须使用 String.valueOf(char[]); 请注意,此方法仅适用于 char 类型的数组。我建议使用 Arrays.toString(Object[]) 将数组转换为字符串。

Second difference is when the object is null, ValueOf() returns a String "null", while toString() will return null pointer exception.

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

回答by Kevin Cruijssen

Most has already been mentioned by other answers, but I just add it for completeness:

大多数已经被其他答案提到了,但我只是为了完整性而添加它:

  1. Primitives don't have a .toString()as they are not an implementation of the Object-class, so only String.valueOfcan be used.
  2. String.valueOfwill transform a given object that is nullto the String "null", whereas .toString()will throw a NullPointerException.
  3. The compiler will use String.valueOfby default when something like String s = "" + (...);is used. Which is why Object t = null; String s = "" + t;will result in the String "null", and not in a NPE.EDIT: Actually, it will use the StringBuilder.append, not String.valueOf. So ignore what I said here.
  1. 原语没有 a,.toString()因为它们不是Object-class的实现,所以只能String.valueOf使用。
  2. String.valueOf会将给定的对象转换为nullString "null",而.toString()将抛出NullPointerException.
  3. String.valueOf当使用like 时,编译器将默认String s = "" + (...);使用。这就是为什么Object t = null; String s = "" + t;会导致 String "null",而不是 NPE 。编辑:实际上,它将使用StringBuilder.append,而不是String.valueOf。所以忽略我这里所说的。

In addition to those, here is actually a use case where String.valueOfand .toString()have different results:

除此之外,这里实际上是一个用例,其中String.valueOf.toString()具有不同的结果:

Let's say we have a generic method like this:

假设我们有一个这样的通用方法:

public static <T> T test(){
  String str = "test";
  return (T) str;
}

And we'll call it with an Integertype like this: Main.<Integer>test().

我们将用一个称之为Integer类型是这样的:Main.<Integer>test()

When we create a String with String.valueOfit works fine:

当我们用String.valueOf它创建一个字符串时,它工作正常:

String s1 = String.valueOf(Main.<Integer>test());
System.out.println(s1);

This will output testto STDOUT.

这将输出test到 STDOUT。

With a .toString()however, it won't work:

随着.toString()但是,它不会工作:

String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);

This will result in the following error:

这将导致以下错误:

java.lang.ClassCastException: class java.lang.Stringcannot be cast to class java.lang.Integer

java.lang.ClassCastException: classjava.lang.String不能强制转换为 classjava.lang.Integer

Try it online.

在线试一下。

As for why, I can refer to this separated question and its answers. In short however:

至于为什么,我可以参考这个分开的问题及其答案。简而言之:

  • When using .toString()it will first compile and evaluate the object, where the cast to T(which is an Stringto Integercast in this case) will result in the ClassCastException.
  • When using String.valueOfit will see the generic Tas Objectduring compilation and doesn't even care about it being an Integer. So it will cast an Objectto Object(which the compiler just ignores). Then it will use String.valueOf(Object), resulting in a Stringas expected. So even though the String.valueOf(Object)will do a .toString()on the parameter internally, we've already skipped the cast and its treated like an Object, so we've avoided the ClassCastExceptionthat occurs with the usage of .toString().
  • 使用时.toString(),它将首先编译和评估对象,其中转换为T(在这种情况下为Stringto 转换Integer)将导致ClassCastException.
  • 使用时,String.valueOf它会在编译期间看到泛型TObject甚至不关心它是Integer. 所以它会投射ObjectObject(编译器会忽略)。然后它将使用String.valueOf(Object),从而产生String预期的结果。因此,即使String.valueOf(Object).toString()在内部对参数执行 a ,我们已经跳过了强制转换并将其视为 an Object,因此我们避免ClassCastException了使用.toString().

Just thought it was worth mentioning this additional difference between String.valueOfand .toString()here as well.

只是认为值得一提的是String.valueOf.toString()这里之间的额外区别。