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

后端 未结 10 768
挽巷
挽巷 2020-12-12 10:21

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

10条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-12 11:01

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

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

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

    Overloading

    It turns out that String.valueOf(null) (note the difference!) does give an NPE ... despite the javadoc. The real explanation1 is obscure:

    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 null is assignment compatible with any reference type.

    3. When there are two or more applicable overloads, the JLS says that the overload for the most specific argument 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 null as a special case.

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

    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 need the formatting to work for null?)

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


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

    2 - Please read "No Best Practices", and pass this reference on to the next person who tells you that it is "best practice" to do something in the programming or IT domains.


    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.

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

    In general, it is better to avoid the null being there in the first place ... unless the null has 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 null that triggered the NPE.

    So how does this apply here?

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

提交回复
热议问题