tags:

views:

653

answers:

11

Actually, this question has no big meaning, I guess.

The situation is: 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.

A: 

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.

Ed Swangren
Casting null will not crash. It will not even throw a NullPointerException, it will just call null to the new type. :)
Bombe
Ahh, my Java ignorance shows through :)
Ed Swangren
+2  A: 

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

Andy White
+2  A: 

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

Henrik Paul
I said that my question has no valueable meaning :) Im just curious what is *theoretically* cheaper. But thanx anyway
Vugluskr
The cost will depend on how efficient the VM is at virtual method calls vs type checking. That's implementation-specific.
Jon Skeet
+3  A: 

If you know you can always cast it to a String, doesn't that mean that the parameter is actually a String?

Why not change the method signature to take a String as a parameter?

Nicolai
+11  A: 

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.

Jon Skeet
+7  A: 

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

euphoria83
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
The method call should get inlined. Using generics to remove the (explicit) cast would be bestest.
Tom Hawtin - tackline
@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
@euphoria83: Inlined by the JIT compiler, not by javac.
Michael Myers
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
+1  A: 

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

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

Joshua
A: 

I would rather overload the method and let JVM decides at compile time

void myMethod(Object o){

}

void myMethod(String str){}
harshit
The resolution between the top and second method is not made at runtime, its made at compile time. In the example below myMethod(Object) is called not myMethod(String)Object o = "string";...myMethod(o)
mP
And that is why overloading is evil :)
willcodejavaforfood
accepted my silly mistake
harshit
A: 

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.
mP
+2  A: 

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

cletus