How Java Handles Method Invocation

In Java, method invocation is categorized into resolution, static dispatch, and dynamic dispatch. These categories differ based on the timing and criteria used to select the method.

1. Resolution (Static Resolution)

Resolution occurs at compile time, which means the target method for invocation is determined during the program’s source code writing and compilation.

Applicable Situations:

2. Static Dispatch

Static dispatch refers to the dispatch process where the method version is determined based on the static type of the reference at compile time.

Example: When multiple overloaded methods with the same name but different parameter types exist, the compiler determines the correct method based on the arguments passed.

class Printer {
    void print(String s) { System.out.println("Printing String: " + s); }
    void print(int i) { System.out.println("Printing int: " + i); }
}

public class Main {
    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print("Hello");  // Static dispatch: prints the print(String s) method
        printer.print(5);        // Static dispatch: prints the print(int i) method
    }
}

3. Dynamic Dispatch

Dynamic dispatch occurs at runtime when the JVM selects the method to invoke based on the actual object type. This process is commonly associated with polymorphism.

Example:

class Animal {
    void sound() { System.out.println("Animal makes a sound"); }
}

class Dog extends Animal {
    @Override
    void sound() { System.out.println("Dog barks"); }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog(); // Dynamic dispatch
        animal.sound();  // Outputs "Dog barks"
    }
}

Important Note:

class Parent {
    int field = 10;
}

class Child extends Parent {
    int field = 20;
}

public class Main {
    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.field);  // Outputs 10, field does not participate in dynamic dispatch
    }
}

4. Some Improvments

import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        Function<String, String> function = (s) -> s.toUpperCase(); // Dynamic dispatch
        System.out.println(function.apply("hello")); // Outputs "HELLO"
    }
}

5. Summary

The Java method invocation process is determined by resolution, static dispatch, and dynamic dispatch.

Resolution happens at compile time, static dispatch depends on static types, and dynamic dispatch relies on actual object types at runtime.

With advancements in Java technologies, particularly JVM optimizations and new features like lambda expressions, method invocation performance and flexibility have significantly improved.