98

I have a method with an Object o parameter.

In this method, I exactly know there is a String in "o" which is not null. There is no need to check, or do something else. I have to treat it exactly like a String object.

Just curious - what is cheaper - cast it to String, or use Object.toString()? Or is it same by time-/cpu-/mem- price?

Update: The method accepts Object because it's the implementation of an interface. There is no way to change the parameter type.

And it can't be null at all. I just wanted to say that I do not need to check it for null or emptyness. In my case, there is always a nonempty string.

1
  • 1
    In .NET world, we measured it and ToString() is faster. Given the reason why this is so, the same is almost certainly true of a jitting JVM.
    – Joshua
    Commented Jan 17, 2014 at 16:18

9 Answers 9

81

casting to a String is cheaper since that doesn't require an external function call, just internal type checking.

6
  • 4
    Have you tested it across multiple JREs? I've seen surprising results for exaclty this situation in .NET. Realistically I doubt that the performance will matter in real life - but casting is better from a defensive coding perspective.
    – Jon Skeet
    Commented Mar 24, 2009 at 7:52
  • The method call should get inlined. Using generics to remove the (explicit) cast would be bestest. Commented Mar 24, 2009 at 11:46
  • @Jon Skeet : I agree that the difference in performance won't be much. @Tom Hawtin : Since the type of the object that will be received is not known at compile time, I cannot see how the method call can get inlined. Can you plz clarify ?
    – euphoria83
    Commented Mar 24, 2009 at 15:32
  • @euphoria83: Inlined by the JIT compiler, not by javac.
    – Michael Myers
    Commented Mar 24, 2009 at 16:57
  • Actually, no, method can not be inlined. Type is only known to be Object, and actual implementation depends on runtime type. Which one is faster still depends on implementation, but as far I remember (I actually did test it with microbenchmark at one point), casting appears to be faster. This is not an obvious answer tho: type checking is not always faster. For String type it can be since it's an object (not interface), and final one at that.
    – StaxMan
    Commented Nov 13, 2009 at 6:49
51

I would use a cast. That validates your "knowledge" that it's a string. If for whatever reason you end up with a bug and someone passes in something other than a string, I think it would be better to throw an exception (which a cast will do) than continue to execute with flawed data.

39

According to Silly performance musings: x.toString() vs (String)x

In thend end, results are surprisingly clear: it is at least twice as fast to cast Object to String than to call Object.toString()

1
  • 2
    I ran that code now, the difference is negligible (Mac, Java 8)
    – Stefan L
    Commented Jan 6, 2017 at 11:24
9

If you know the Object o is a String, I'd say just cast it to a String and enforce it that way. Calling toString() on an object that you know for sure is a String might just add confusion.

If Object o might be anything other than a String, you'll need to call toString().

1
  • 1
    This is the correct answer for me. Why? Because casting (string)Registry.GetValue... throws an exception for trying to cast an Int32 object, whereas Registry.GetValue...ToString() works as expected.
    – gravity
    Commented Jun 8, 2016 at 15:00
3

I wouldn't be too concerned by the performance, if this operation is done even just a few thousand times a second - there's no tangible difference.

I would, however, be concerned of "knowing" the input. You have a method that accepts an Object and you should treat it as such, i.e. you shouldn't know anything about the parameter, other than it adheres to the Object interface, which happens to have a toString() method. In this case, I would strongly suggest using that method instead of just assuming anything.

OTOH, if the input is always either String or null, just change the method to accept Strings, and check explicitly for nulls (which you should do anyways whenever dealing with non-primitives...)

2
  • I said that my question has no valueable meaning :) Im just curious what is theoretically cheaper. But thanx anyway
    – Vugluskr
    Commented Mar 24, 2009 at 7:07
  • The cost will depend on how efficient the VM is at virtual method calls vs type checking. That's implementation-specific.
    – Jon Skeet
    Commented Mar 24, 2009 at 8:47
2

Given that the reference type is an Object and all Objects have a toString() just call object.toString(). String.toString() just returns this.

  • toString() is less code to type.
  • toString() is less bytecode.
  • casting is an expensive operation VS a polymorphic call.
  • the cast could fail.
  • Use String.valueOf( object ) which just calls object.toString() if its not null.
1

If what you have in "o" is a String then there is not much of a difference (likely the cast is faster, but that is a VM/Library implementation thing).

If "o" may not be a String but it is supposed to be a String then the cast is what you want (but you should make the method take a String instead of an Object).

If "o" could be any type then you have to use the toString - but be sure to check for null first.

void foo(final Object o)
{
    final String str;

    // without this you would get a class cast exception
    // be wary of using instanceof though - it is usually the wrong thing to do
    if(o instanceof String)
    {
        str = (String)o;
    }    
}

or

void foo(final Object o)
{
    final String str;

    // if you are 100% sure that o is not null then you can get rid of the else
    if(o != null)
    {
        str = o.toString();
    }
}

I'd rather code the last one as:

void foo(final Object o)
{
    final String str;

    if(o == null)
    {
        throw new IllegalArgumentException("o cannot be null");
    }

    str = o.toString();
}
1
  • The first 2 snippets won't really compile (the final variable might not have been initialized). You need an else that will either throw an exception or initialize str to something.
    – Bruno Reis
    Commented Jul 29, 2011 at 12:02
1

I found oddly that the cast was slower than the vtable lookup implied by the tostring call.

1

There cannot be a 'null string in o'. If o is null, it does not contain a null string, it is just null. Just check o for null first. If you cast or call ToString() on null you will crash.

1
  • 2
    Casting null will not crash. It will not even throw a NullPointerException, it will just call null to the new type. :)
    – Bombe
    Commented Mar 24, 2009 at 9:39

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