4

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?

Kev
  • 118,037
  • 53
  • 300
  • 385
James T
  • 125
  • 1
  • 8

4 Answers4

2

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));
  }
}
Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202
  • Actually I do not agree with this phrase "dynamic dispatch allows the actual implementation of the Meth1 method to be determined at runtime". Polymorphic dispatch allows for controlled dynamism, and though not statically bound, it is statically safe (you are guaranteed that the receiver method exists). – ddimitrov Aug 20 '11 at 16:49
  • so are you saying my example is dynamic dispatch because i'm passing in parameter A a, where a is new B() or new C()? – James T Aug 20 '11 at 16:51
  • "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" that would require closed universe, which is too strong restriction (i.e. prohibits use of Dunamic Proxies). What you have instead is the monomorphic optimization and speculative inlining. Check the HotSpot wiki: http://wikis.sun.com/display/HotSpotInternals/PerformanceTechniques – ddimitrov Aug 20 '11 at 16:51
  • @James, No - statically typed polymorphic dispatch. Technically speaking you have dynamic binding, but that has nothing to do with the dynamic dispatch (better forget about it if you don't want to get even more confused). – – ddimitrov Aug 20 '11 at 16:55
  • @ddmitrov, I believe what you call statically typed polymorphic dispatch, everybody else calls dynamic dispatch. http://c2.com/cgi/wiki?DynamicDispatch – Ionuț G. Stan Aug 20 '11 at 16:59
  • @Ionut, the C2 wiki is far from being the reference source from all things Java. Here is an article, describing the 4 pre-Java 7 invocatoin bytecodes: http://www.artima.com/underthehood/invocationP.html; and this is one for the new 'invokedynamic' bytecode, which is not accessible from the Java language: http://java.sun.com/developer/technicalArticles/DynTypeLang/; While not authoritative, these articles show you the terminology for Java (I could quote the JVM spec if you need it). – ddimitrov Aug 21 '11 at 07:30
  • @Ionut In particular, the virtual call is bound to a method signature at compile time and the method signature is bound to implementation ar run time. In a dynamic call, the method signature is determined at runtime using application/framework specific rules. – ddimitrov Aug 21 '11 at 07:31
0

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.

0

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.

Community
  • 1
  • 1
-1

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
ddimitrov
  • 3,293
  • 3
  • 31
  • 46
  • 1
    the only difference between the two is the argument 1 and 2? I'm a little confused because my ex-lecturer told me dynamic dispatch is possible in Java, because they mentioned an example of it in a lecture..... – James T Aug 20 '11 at 16:22
  • @James T, single dynamic dispatch is indeed possible in Java. Dynamic dispatch means that the object on which the method is called is determined at runtime. – Ionuț G. Stan Aug 20 '11 at 16:24
  • Hi, Is what i have written an example of single dynamic dispatch? – James T Aug 20 '11 at 16:26
  • 1
    Java does support dynamic dispatch. How do you say 'Java does not support dynamic dispatch' ? – Bhaskar Aug 20 '11 at 16:31
  • Sorry James, dynamic dispatch in Java does not exist, so I can not give you an example. The best I could come up was counterfactual example with the code above. You can take it, put it in a debugger and run it under Java (static dispatch) and Groovy (dynamic dispatch). In any case one assert will succeed and the other will fail. – ddimitrov Aug 20 '11 at 16:32
  • Why do you give an example using method **overloading** (which is indeed a very nice WTF example due to autoboxing/autoaunboxing)? Dynamic dispatch concerns method **overriding**. – Ionuț G. Stan Aug 20 '11 at 16:36
  • @Bhaskar, I am saying it because of my knowledge of the definition of what dynamic invocation is (stated above) and Java Language Specification 15.12.1. Why are you saying Java supports dynamic invocation? – ddimitrov Aug 20 '11 at 16:37
  • @Ionut, Dynamic dispatch is finding the invocation target based on runtime types, in this case the right target happens to be an overload in the same inheritance hierarchy and is a frequent gotcha. It could have been unrelated class with the same method name and compatible signature and then we would have called it "duck typing". – ddimitrov Aug 20 '11 at 16:39
  • I don't think your example is good because of auto(un)boxing. So, method overloading is determined at compile time, and in your example, at **compile time**, `c` has type `Collection` which only defines `remove(Object e)`. As such, the compiler decides to box the `int` to an `Integer`, and as such, at runtime, the actual method being called will be `ArrayList.remove(Object e)`, instead of `ArrayList.remove(int index)`. So, IMHO, this example is flawed because of autoboxing. – Ionuț G. Stan Aug 20 '11 at 16:53
  • I just realized that here we fell victim of the is-dynamic vs how-dynamic argument - check the slides from Brian Gotz's presentation [Java Past, Present, and Future](http://www.infoq.com/presentations/java-history-present-future). In particular: "Static method overload resolution, but dynamically linked (and verified, with dynamic enforcement of accessibility). Dynamic dispatch on receiver, static dispatch on arguments. – ddimitrov Jan 20 '15 at 06:41