James T
James T

Reputation: 125

Is this dynamic dispatch?

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

Answers (4)

JairoV
JairoV

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

almondandapricot
almondandapricot

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

Ionuț G. Stan
Ionuț G. Stan

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

ddimitrov
ddimitrov

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

Related Questions