Normally, Java optimizes the virtual calls based on the number of implementations encountered on a given call side. This can be easily seen in the results of my benchmark, w
I can confirm the findings. See these results (recompilations omitted):
$ /extra/JDK8u5/jdk1.8.0_05/bin/java Main
overCode : 14.135000000s
hashCode : 14.097000000s
$ /extra/JDK7u21/jdk1.7.0_21/bin/java Main
overCode : 14.282000000s
hashCode : 54.210000000s
$ /extra/JDK6u23/jdk1.6.0_23/bin/java Main
overCode : 14.415000000s
hashCode : 104.746000000s
The results are obtained by calling methods of class SubA extends Base repeatedly.
Method overCode() is identical to hashCode(), both of which just return an int field.
Now, the interesting part: If the following method is added to class Base
@Override
public int hashCode(){
return super.hashCode();
}
execution times for hashCode aren't different from those for overCode any more.
Base.java:
public class Base {
private int code;
public Base( int x ){
code = x;
}
public int overCode(){
return code;
}
}
SubA.java:
public class SubA extends Base {
private int code;
public SubA( int x ){
super( 2*x );
code = x;
}
@Override
public int overCode(){
return code;
}
@Override
public int hashCode(){
return super.hashCode();
}
}