17

I know there are two types of casting that are implicit and explicit castings. I read different questions on the StackOverflow such as this, this and this but I am still wondering what is the cost of casting in Java and is it a good idea to avoid it? What is the best practice for it?

There are 2 types of casting:

String s = "Cast";
Object o = s; // implicit casting

Object o = someObject;
String s = (String) o; // explicit casting

In this second case, there is overhead in runtime, because the two type must be checked and in case that casting is not feasible, the JVM must throw a ClassCastException.

Someone said it is better to profile the application to make sure casting is useful or not.

Community
  • 1
  • 1
Jack
  • 6,430
  • 27
  • 80
  • 151
  • 2
    Avoid the need to cast in the first place, whenever possible. – Bathsheba Oct 13 '14 at 08:47
  • When speaking about maintainability costs, I think casts have a very high cost, so it is good to avoid them. But I think you didn't meant that type of cost in the first place. – SpaceTrucker Oct 13 '14 at 08:48
  • 4
    You are micro optimising... Casting has a place in the world, but should be use judiciously. You will know when you absolutely need to cast. – Leon Oct 13 '14 at 08:54
  • 1
    Don't use Cast as mush as possible, it can be annoying maintaining those. – mcr619619 Oct 13 '14 at 08:57
  • While this doesn't answer your question, in many cases you should try to be as general as possible and as specific as necessary. So, if in the first case you will never care about whether `s` is a String or any other Object as long as it is an Object, use `Object o = "Cast";` A good example is [programming to an interface](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface). You may also want to read up on Java Generics. – blalasaadri Oct 13 '14 at 09:26
  • @phil_20686 plase read the question first before declaring duplicates. thanks – Jack Oct 13 '14 at 21:38

5 Answers5

34

Type casts are usually an indicator that you should think about an alternative solution for your problem. After all, everything which can be checked at compile time will help the programmer.

However, sometimes type casts are unavoidable and in Generic code they happen often without the programmer ever noticing. Therefore, significant effort was made to make type cast quite fast.

In the past, a runtime type cast included the possibility that the super type hierarchy has to be traversed to find a match. Today, a type cast is nothing more than a number comparison plus a simple pointer comparison, if not optimized away when the analyzer could prove that the cast will always succeed.

In order to make type casting fast, every class knows its depth in the class hierarchy and has a table containing all super types. To test a class, its depth is compared and if the depth is lower, it can’t be a compatible class and the type cast fails. Otherwise, the table’s entry at the position equal to the depth of the check class must match exactly, so that’s all to test.

For example:

Object o=new JButton();
Container c=(Container)o;

Class Container has a depth of 3 and a the following table of superclasses:

Object
Component
Container

Class JButton has a depth of 5 and a the following table of superclasses:

Object
Component
Container
JComponent
JButton

Now the type cast checks:

  • JButton has a depth of 5 which is ≥ 3, the depth of Container, so the test might succeed
  • The third entry in the tables is checked and is an exact match:

    Object          Object
    Component       Component
    Container   <=> Container
    JComponent
    JButton
    

So the hierarchy is not traversed anymore and the type cast operation is rather cheap.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • how about down casting? – Jack Oct 13 '14 at 21:45
  • 4
    The example in my answer *is* downcasting as it casts from `Object` to `Container`. But the point about runtime type checks is that the type of the local variable (here `Object`) doesn’t matter; only the object’s actual type (here `JButton`) is checked against the type of the cast (`Container`). In contrast, most upcasting operations are elided at compile time, they don’t even generate byte code instructions. – Holger Oct 14 '14 at 08:44
14

In this second case, there is overhead in runtime, because the two type must be checked and in case that casting is not feasible, JVM must throw a ClassCastException.

Not necessarily, it is very likely that for a simple case like this the JIT will be able to figure out that the cast will always work and will optimise the check away. Running a microbenchmark confirms the assumption:

Benchmark                  Mode  Samples  Score   Error  Units
c.a.p.SO26335959.cast      avgt        5  3.177 ± 0.060  ns/op
c.a.p.SO26335959.noCast    avgt        5  3.174 ± 0.108  ns/op

In more complicated situations, branch prediction will work in your favour too.

Bottom line, as usual: measure, don't guess!

assylias
  • 321,522
  • 82
  • 660
  • 783
2

Unless you are writing a performance critical loop for a server, then you should not be thinking about what is faster. Think instead of what makes clean, maintainable code. And casting is almost always in tension with those goals, and can usually be eliminated by better code structure.

To answer your questions. Up casting usually costs virtually nothing, (when you change the reference type to a parent class of the object). Knowledge of the reference type is enough to decide if uptyping is valid, it just gets the class loader to look up the inheritance map. It is also a check that can be done at compile time. (Unless the reference type was already down cast).

Down casting is slower, as the JVM must take the reference, look up the actual object class, which may have many types (implement many interfaces), and for each such interface it then checks to see if you are casting to a valid type by (more or less) uptyping on each of the (possibly many) reference types. Since down casting makes reference to the actual object, it can only be checked at run time.

Down casting is not usually a performance issue anyway, (and is probably JVM dependent), but I believe that it might be possible to make it so via a pathological choice of inheritance structure. Especially in languages that allow multiple inheritance.

You might find this link interesting

phil_20686
  • 4,000
  • 21
  • 38
0

Avoid cast if possible. Casted stuff is harder to maintain and therefore has higher cost - if you need to check an object, use 'instanceof'(for example:

if (o instanceof String) {
   // do something
}

the JVM uses this to check, whether your object is a String and will return true because you set o = s).

If you change superclass of a class later on in your code, casts may no longer work and you need to rework your code, while behind instanceof you can simply change the class it should be checked for.

//please correct me if I am wrong on anything.

About the cost of casting time-wise: As I mentioned before, it will cost a lot of time if you change your code, or change superclasses, later. Runtime-wise, as casting is done because there is no type-safety, it takes less runtime for a check then it costs for an exception due to an unpermitted cast attempt.

  • 8
    doesn't answer the question, which is "what is the cost of casting" – Ross Drew Oct 13 '14 at 08:57
  • While a "casting should be avoided where possible" part has a place in an answer I believe the OP means a literal time cost. As in a cast is equivalent to a ..... operation and is a quick/slow operation – Richard Tingle Oct 13 '14 at 09:27
  • "What is the cost" is not the only question asked. "Is it a good idea" was the other question asked and this post answers _that_ question. – Erwin Smout Oct 13 '14 at 09:40
0

Generated byte code contains instruction checkcast. So yes, casting costs something. Though it's not expensive and most likely it will be optimized by JIT in runtime.

ponomandr
  • 1,523
  • 13
  • 21