Reputation: 125
Is this dynamic dispatch:
abstract class A{
public method Meth1(){
//somecode
}
}
class B extends A{
}
class C extends A{
}
In another class entirely:
Some_Method(A a){
a.Meth1();
}
I'm not sure if this is dynamic dispatch because the behaviour is the same on both subclasses?
If it's not, would it be dynamic dispatch if the behaviour was defined per the subclasses?
Upvotes: 4
Views: 2829
Reputation: 2104
Yes, it is!.
Because in Java all instance methods are virtual by default. (Can you write virtual functions / methods in Java?)
Then resolve a.Meth1() needs to be done in runtime. Remember that you can load a new JAR dynamically with a class that derives from A having an override of that method.
Upvotes: 0
Reputation: 331
It is dynamic dispatch because the compiler cannot assume, when producing bytecode for the calling class, that it knows the full universe of classes.
Neither will the bytecode interpreter or the JIT compiler at runtime, at least because classes could be loaded dynamically.
In my view, this leaves java no other option than use dynamic dispatch, and not 'cut corners' i.e. optimise calls into base class calls.
Upvotes: 0
Reputation: 179189
I'm not sure what you say about you're specific question (there might be some implementation specific optimization that will bypass runtime type checking if the invoked method is statically known to be declared in just one class), but indeed, dynamic dispatch allows the actual implementation of the Meth1
method to be determined at runtime. So, even if right now, neither B
nor C
override Meth1
, later, if overriden, dynamic dispatch will ensure that if the runtime type of the formal param a
is B
, then the actual implementation will be that on B
. Similarly in the case of C
.
Contrast this with method overloading in Java where the actual method is determined at compilation time based on the declared type of used arguments.
public class Overloading {
public static class User {}
public static class Admin extends User {}
public static String foo(User user) {
return "User specific method";
}
public static String foo(Admin admin) {
return "Admin specific method";
}
// This will print "User specific method" two times, because both
// user1 and user2 have same compile time type, i.e., User. Runtime
// type does not matter.
public static void main(String[] args) {
User user1 = new User();
System.out.println(foo(user1));
User user2 = new Admin();
System.out.println(foo(user2));
}
}
Upvotes: 2
Reputation: 3343
Dynamic dispatch is when a method implementation is picked based on the actual and not the declared type. Java does not support dynamic dispatch, except through reflection. This is statically typed polymorphic dispatch.
If you have a single implementation loaded, the JVM will apply momomorphic optimization (yielding very fast calls) which will be undone when the JVM sees a second implementation passed to the same code.
You might have heard about the new 'invokedynamic' bytecode, which implements dynamic dispatch in the JVM, but it is intended to be used by other JVM languages and Java programs will not use it except when doing bytecode generation.
[Edit] Here is a simple example:
Collection<Integer> c = new ArrayList<Integer>(Arrays.asList(2, 1, 0));
c.remove(2); // Collection.remove(E element) or List.remove(int idx)?
assert c.equals(Arrays.asList(1, 0)); // passes in case of static dispatch
assert c.equals(Arrays.asList(2, 1)); // fails - would pass in case of dynamic dispatch
Upvotes: -1