Skip to content

Dynamic Binding

Here is a step-by-step guide on how to deal with dynamic binding.

Summary of Steps

Dynamic binding can be split into 2 parts -- compile time where the method descriptor is determined and runtime where the method is being invoked

Compile Time

During compile time, the method descriptor is recorded.

1
curr.foo(obj);

Steps

  1. Determine compile-time type of target curr i.e. CTT(curr)
  2. Determine compile-time type of arg obj i.e. CTT(obj)
  3. Find all methods with same name foo that are accessible in class CTT(curr)
    • Includes superclasses
    • Appropriate access modifiers (public)
  4. From above methods, find those compatible with CTT(obj)
    • Same number of parameters
    • Argument is supertype of CTT(obj)
  5. From above, choose most specific method
    • If none is most specific, compilation error
    • Store method descriptor of most specific method

Runtime

During runtime, compiler tries to invoke the method according to method descriptor stored.

1
curr.foo(obj);

Steps

  1. Retrieve method descriptor from compile-time step
  2. Determine runtime type of target curr i.e. RTT(curr)
  3. Starting from RTT(curr) class, find 1st method that match the method descriptor as retrieved from Step 1.
  4. If not found, go up the heirachy of class to find

Runtime type

Remember that we do not consider the runtime type of the argument passed in. The method descriptor was already decided during compile time.

Step-by-step

Example 1

This is an example where a method is successfully invoked.

Example 1
1
2
3
4
5
6
7
8
boolean contains(Object[] array, Object obj) {
    for (Object curr : array) {
        if (curr.equals(obj)) {
            return true;
        }
    }
    return false;
}

Compile Time

1
2
3
boolean contains(Object[] array, Object obj) {
    for (Object curr : array) {
        if (curr.equals(obj)) {
CTT(curr) return type method name CTT(obj)
Object boolean equals
  1. Determine compile-time type of target curr i.e. CTT(curr)
    • From line 2, CTT(curr) = Object
1
2
3
boolean contains(Object[] array, Object obj) {
    for (Object curr : array) {
        if (curr.equals(obj)) {
CTT(curr) return type method name CTT(obj)
Object boolean equals Object
  1. Determine compile-time type of target curr i.e. CTT(curr)
    • From line 2, CTT(curr) = Object
  2. Determine compile-time type of arg obj i.e. CTT(obj)
    • From line 1, CTT(obj) = Object
1
2
3
4
5
6
7
class Object {
..

public boolean equals(Object obj) {
    // implementation omitted
}
}
Class return type method name CTT(obj)
Object boolean equals Object
  1. Determine compile-time type of target curr i.e. CTT(curr)
    • From line 2, CTT(curr) = Object
  2. Determine compile-time type of arg obj i.e. CTT(obj)
    • From line 1, CTT(obj) = Object
  3. Find all methods with same name equals that are accessible in class Object
    • Only 1 found here, and is public
1
2
3
4
5
6
7
class Object {
..

public boolean equals(Object obj) {
    // implementation omitted
}
}
Class return type method name CTT(obj)
Object boolean equals Object
  1. Determine compile-time type of target curr i.e. CTT(curr)
    • From line 2, CTT(curr) = Object
  2. Determine compile-time type of arg obj i.e. CTT(obj)
    • From line 1, CTT(obj) = Object
  3. Find all methods with same name equals that are accessible in class Object
    • Only 1 found here, and is public
  4. Is the method compatible with CTT(obj)?
    • Method takes in an Object, Object <: Object, compatible
1
2
3
4
5
6
7
class Object {
..

public boolean equals(Object obj) {
    // implementation omitted
}
}
return type method name param type
boolean equals (Object)
  1. Determine compile-time type of target curr i.e. CTT(curr)
    • From line 2, CTT(curr) = Object
  2. Determine compile-time type of arg obj i.e. CTT(obj)
    • From line 1, CTT(obj) = Object
  3. Find all methods with same name equals that are accessible in class Object
    • Only 1 found here, and is public
  4. Is the method compatible with CTT(obj)?
    • Method takes in an Object, Object <: Object, compatible
  5. Find most specific method
    • Since there is only 1, it is the most specific
    • Method descriptor stored is boolean equals(Object)

Runtime

Method descriptor
boolean equals(Object)
  1. Retrieve method descriptor from compile-time step
Method descriptor
boolean equals(Object)
  1. Retrieve method descriptor from compile-time step
  2. Determine runtime type of target curr i.e. RTT(curr)
    • Let's say Circle[] is passed as argument to Object[] array, so RTT is Circle
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Circle {
    public boolean equals(Circle obj) {
        // implementation omitted
    }

    @Override
    public boolean equals(Object obj) {
        // implementation omitted
    }
}
Method descriptor
boolean equals(Object)
  1. Retrieve method descriptor from compile-time step
  2. Determine runtime type of target curr i.e. RTT(curr)
    • Let's say Circle[] is passed as argument to Object[] array, so RTT is Circle
  3. Try to find matching method descriptor in class Circle
    • This method does not match as its method descriptor is boolean equals(Circle).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Circle {
    public boolean equals(Circle obj) {
        // implementation omitted
    }

    @Override
    public boolean equals(Object obj) {
        // implementation omitted
    }
}
Method descriptor
boolean equals(Object)
  1. Retrieve method descriptor from compile-time step
  2. Determine runtime type of target curr i.e. RTT(curr)
    • Let's say Circle[] is passed as argument to Object[] array, so RTT is Circle
  3. Try to find matching method descriptor in class Circle
    • This method matches
    • Circle::equals(Object) gets invoked.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Object {
    public boolean equals(Object obj) {
        // implementation omitted
    }
}

class Circle {
    public boolean equals(Circle obj) {
        // implementation omitted
    }
    // No other equals method
}
Method descriptor
boolean equals(Object)
  1. Retrieve method descriptor from compile-time step
  2. Determine runtime type of target curr i.e. RTT(curr)
    • Let's say Circle[] is passed as argument to Object[] array, so RTT is Circle
  3. Try to find matching method descriptor in class Circle
    • If Circle does not have matching method descriptor, try to find in superclass
    • Object::equals(Object) is invoked in this case.