1

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 ?

Ismail Marmoush
  • 13,140
  • 25
  • 80
  • 114

4 Answers4

4

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.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
Ralph
  • 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
1

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
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
1

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;
}
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
0

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

Favonius
  • 13,959
  • 3
  • 55
  • 95