189

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

3
  • 17
    Primitive types don't have a "toString".. so String.valueOf is used. For objects that override toString, I think String.valueOf might call that instead. Not sure about that part though.
    – Brandon
    Commented Dec 14, 2014 at 2:22
  • 1
    @Brandon You are correct, it does exactly that, except that it checks for null first.
    – azurefrog
    Commented Dec 14, 2014 at 2:30
  • The first comment here I think makes the most sense if it is correct. You must use String.valueOf in certain situations where the target is a primitive type. Commented Aug 10, 2017 at 20:06

11 Answers 11

257

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

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

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 NullPointerException will be thrown, so arguably, it's less safe.

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
} 
9
  • 11
    This is the best answer. Read and rely on the javadocs, not the code. (The code could in principle be different for different versions / releases of Java.)
    – Stephen C
    Commented Dec 14, 2014 at 2:32
  • 8
    @Brandon - Incorrect. It only needs to change if the behaviour changes in a way that invalidates the javadoc. 1) The chances of that happening for this method are ZERO. They won't make a change that warranted a change in the spec, and if they did then they would change the spec. 2) It doesn't invalidate my advice. If you read the javadoc, then you will see that the documented behaviour has changed!
    – Stephen C
    Commented Dec 14, 2014 at 2:42
  • 5
    Wouldn't the method that throws the exception be more safe? Usually, when your code throws a NullPointerException, it's sort of a good thing. It may not feel good to the developer in the moment ("aww, no, now I need to go back and fix my code"), but since the error was thrown, you found out you needed to fix something. Left the other way, you're exposing the "null" directly to the user and not getting an error reported unless you explicitly check for one, which seems to me less safe.
    – Tim M.
    Commented Feb 6, 2018 at 18:15
  • 4
    Just to be clear, you can't actually call String.valueOf(null), that's an NPE. It only works for objects that are null.
    – Noumenon
    Commented Mar 17, 2019 at 23:20
  • 2
    That's not the explanation. The String.valueOf(null) actually resolves to the valueOf(char[]) overload. This is because char[] is a more specific type than Object.
    – Stephen C
    Commented Nov 26, 2019 at 15:37
26

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

1) If string is null,

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

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:

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

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

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:

public String toString()
4
21

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

7

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.valueOf can be used.
  2. String.valueOf will transform a given object that is null to the String "null", whereas .toString() will throw a NullPointerException.
  3. The compiler will use String.valueOf by 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.

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

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 Integer type like this: Main.<Integer>test().

When we create a String with String.valueOf it works fine:

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

This will output test to STDOUT.

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

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

This will result in the following error:

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.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 String to Integer cast in this case) will result in the ClassCastException.
  • When using String.valueOf it will see the generic T as Object during compilation and doesn't even care about it being an Integer. So it will cast an Object to Object (which the compiler just ignores). Then it will use String.valueOf(Object), resulting in a String as 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 ClassCastException that occurs with the usage of .toString().

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

1
  • The last time I cared about this, which would have been around JDK 1.2, ("" + x) compiled to String.valueOf(x), but anything more complicated used a StringBuffer (we didn't have StringBuilder then).
    – Neil
    Commented Jun 25, 2019 at 12:27
4

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
3

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

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:

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();
}
1
  • 2
    Not true, use both valueOf and toString on a char array and feast your eyes.
    – Artanis
    Commented Dec 19, 2018 at 22:06
1

When argument is null, the String.valueOf returns "null", but Object.toString throws NullPointerException, that's the only difference.

0

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

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.

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

3
  • Hi @Tom this is true for an array of any type, However If you are using Arrays.toString(Object [ ] ), you can convert an array of any type to string. Commented Jan 12, 2017 at 13:03
  • Hi @Tom Object.toString() returning a garbage value is true for an array of any type, you are right that String.valueOf(Array) will give a correct string only for an array of char type. I should have mentioned that, thanks, I will edit it. Commented Jan 12, 2017 at 13:14
  • 1
    That isn't a garbage value, it is the classname and the hashcode (JavaDoc).
    – Tom
    Commented Jan 12, 2017 at 13:51
0

String.valueOf() can be used with primitive types which do not have toString() methods.

-1

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 ...

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()
2
  • Why failed? what's the problem? Commented Aug 10, 2016 at 16:54
  • The explanation is that you are actually calling valueOf(char[]) rather than valueOf(Object). The behavior of valueOf(char[]) is significantly different to char[].toString(). But either way, this answer is not apropos because you are calling a different overload to the one the Question asks about.
    – Stephen C
    Commented May 21, 2020 at 23:17
-2

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.

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.