Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Binding and Dispatching in Java?

There are too many associated names: Early and Late Binding, Static and Dynamic Dispatch, Runtime vs. Compile-time Polymorphism, etc. that I don't understand the difference.

I found a clear explanation, but is it correct? I'll paraphrase JustinC:

Binding: is determining the type of a variable (object?). If it's done at compile time, its early binding. If it's done at run time, it's late binding.

Dispatch: is determining which method matches the method call. Static Dispatch is computing methods at compile time, whereas dynamic dispatch is doing it at run time.

Is Binding matching up primitive and reference variables with primitive values and objects respectively?

Edit: Please give me some clear reference material so I can read more about this.

like image 570
Code_Steel Avatar asked Jan 07 '17 17:01

Code_Steel


2 Answers

I believe the confusion typically comes from how overloaded these terms are.

We program our programs in a high level language, and either a compiler or an interpreter must transform that into something a machine actually understands.

In coarse terms, you can picture a compiler transforming our method code into some form of machine code. If the compiler knew at that point exactly where in the memory that method would reside when we run our program later, then it could safely go and find every method invocation of this compiled method and replace it with a jump to this address where the compiled code resides, right?.

Well, materializing this relationship is what I understand as binding. This binding, though, could happen at different moments, for example at compile time, linking time, load time, or at run time depending on the design of the language.

The terms static and dynamic are generally used to refer to things bound before run time and at run time, respectively.

Later binding times are associated with greater flexibility, earlier binding times are associated with greater efficiency. Language designers have to balance these two aspects when they're creating a language.

Most object-oriented programming languages support subtype polymorphism. In these languages, virtual methods are bound at runtime depending on the dynamic type of the object at that point. In other words, virtual method invocations are dispatched to the appropriate implementation at runtime based on the dynamic type of the object implementation involved and not based solely on its static type reference.

So, in my opinion, you must first bind the method invocation to a specific implementation or execution address, and then you can dispatch an invocation to it.

I had answered a very similar question in the past in which I demonstrate with examples how this happens in Java.

I would also recommend reading the book Programming Language Pragmatics. It is a great reference to learn all this kind of stuff from a theoretical standpoint.

like image 87
Edwin Dalorzo Avatar answered Sep 24 '22 01:09

Edwin Dalorzo


When you're looking for "low level" definitions, probably the only legitimate source is our old friend - the JLS. Though it does not give a clear definition in this case, the context in which it uses each term might be enough.

Dispatch

This term is indeed mentioned in procedures of determining which method to call.

15.12.2. Compile-Time Step 2: Determine Method Signature

The second step searches the type determined in the previous step for member methods. This step uses the name of the method and the argument expressions to locate methods that are both accessible and applicable, that is, declarations that can be correctly invoked on the given arguments.

There may be more than one such method, in which case the most specific one is chosen. The descriptor (signature plus return type) of the most specific method is the one used at run time to perform the method dispatch. A method is applicable if it is applicable by one of strict invocation

The elaboration on what is the "most specific" method is done in 15.12.2.5 Choosing the Most Specific Method.

As for "dynamic dispatch",

JLS 12.5. Creation of New Class Instances:

Unlike C++, the Java programming language does not specify altered rules for method dispatch during the creation of a new class instance. If methods are invoked that are overridden in subclasses in the object being initialized, then these overriding methods are used, even before the new object is completely initialized.

It includes

Example 12.5-2. Dynamic Dispatch During Instance Creation

class Super {

  Super() {
      printThree();
  }

  void printThree() {
      System.out.println("three");
  }
}

class Test extends Super {

  int three = 3;

  void printThree() {
      System.out.println(three);
  }

  public static void main(String[] args) {
      Test t = new Test();
      t.printThree();
  }
}

Output:

0
3

This happens because during the constructor call chain, Super's constructor calls printThree, but due to dynamic dispatch the method in Test is called, and that is before the field is initialized.

Binding

This term is used in contexts of class member access.

Example 15.11.1-1. Static Binding for Field Access demonstrates early and late bindings. I will summarize the examples given there for the lazy of us:

class S {
    int x = 0;
    int z() { return x; }
}

class T extends S {
    int x = 1;
    int z() { return x; }
}

public class Test1 {

    public static void main(String[] args) {
        S s = new T();
        System.out.println("s.x=" + s.x);
        System.out.println("s.x=" + s.z());
    }
}

Output:

s.x=0
s.x=1

Showing that the field uses "early binding", while the instance method uses "late binding":

This lack of dynamic lookup for field accesses allows programs to be run efficiently with straightforward implementations. The power of late binding and overriding is available, but only when instance methods are used.

Binding is also used in regards to determining the type of a generic,

8. Classes

Classes may be generic (§8.1.2), that is, they may declare type variables whose bindings may differ among different instances of the class.

Meaning that if you create 2 instances of List<String>, the bindings of String in both instances are different from each other.

This also applies to raw types:

4.8. Raw Types

class Outer<T>{
    T t;
    class Inner {
        T setOuterT(T t1) { t = t1; return t; }
    }
}

The type of the member(s) of Inner depends on the type parameter of Outer. If Outer is raw, Inner must be treated as raw as well, as there is no valid binding for T.

Meaning that declaring Outer outer (this will generate a raw type warning) does not allow to determine the type of T (obviously - it wasn't defined in the declaration).

like image 33
user1803551 Avatar answered Sep 21 '22 01:09

user1803551