when I create Animal x=new Dog();
and I want to use Dog functions, I would have to cast right ? ((Dog)x).bark();
so let's say I would use this many times in for loops does that result in lower performance ? also is there any other way than casting each time ?

- 13,140
- 25
- 80
- 114
-
1might be helpful http://stackoverflow.com/questions/2170872/does-java-casting-introduce-overhead-why – Nishant Dec 28 '10 at 12:08
-
4You may be asking the wrong question. "Creating an Animal as `new Dog()` and then using Dog functions" suggests a questionable design. – David Gelhar Dec 28 '10 at 12:19
-
1@David, Man! your comment made me change the whole program, and yes you're right thanks alot ! – Ismail Marmoush Dec 28 '10 at 13:12
4 Answers
A cast like
Dog dog = (Dog) animal;
is a so called "Check" cast. So at runtime it is a simple if-statement (is the instance of animal implementing Dog) which throws a ClassCastException
. So at least it will not provide any reasonable performance overhead if the cast is ok, but if it fails it thows an exception, and exception handling is a performance consuming "operation".
So if you cast someting, and the cast will not fail, I belive there is no performance issue. But if you have a cast that fails very often, then you should change you algorithm a little bit.

- 292,901
- 67
- 465
- 588

- 118,862
- 56
- 287
- 383
-
Its not a simple if-statement. It is a series of if statements :). Checkout this link http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc2.html – Favonius Dec 28 '10 at 12:29
Casting always adds an overhead but it is difficult to say whether it will be bottleneck to your application. This will depend on your scenario. You could avoid multiple casts by performing it outside of the loop:
Animal x = new Dog();
Dog dog = (Dog)x;
Now loop and call dog.bark() as many times as you like

- 1,023,142
- 271
- 3,287
- 2,928
What I tend to do is use the implementation type locally while returning the Base type. Something like this:
public Animal createAnimal(){
Dog dog = new Dog();
dog.bark();
dog.bite();
dog.houl();
return dog;
}

- 292,901
- 67
- 465
- 588
Lets say the Dog class is like this:
package test;
public class Dog extends Animal {
public void bark(){
System.out.println("Woof woof");
}
}
And the Animal class is like this:
package test;
public class Animal {
public void sayHello(){
System.out.println("Hello !!");
}
public static void main(String[] args) {
Animal a = new Dog();
a.sayHello();
((Dog)a).bark();
}
}
If you see the generated bytecode it will look like this:
Compiled from "Animal.java"
public class test.Animal extends java.lang.Object{
public test.Animal();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public void sayHello();
Code:
0: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #21; //String Hello !!
5: invokevirtual #23; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public static void main(java.lang.String[]);
Code:
0: new #31; //class test/Dog
3: dup
4: invokespecial #33; //Method test/Dog."<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #34; //Method sayHello:()V
12: aload_1
13: checkcast #31; //class test/Dog
16: invokevirtual #36; //Method test/Dog.bark:()V
19: return
}
So as you see there is an extra checkcast
here, which is resolved as per this link:
http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc2.html
As to avoid the delay in loop like blocks: Cast outside the loop and then use...

- 13,959
- 3
- 55
- 95