DEV Community

Vigneshwaralingam
Vigneshwaralingam

Posted on

In a Method calling what happens in a compile time and Run Time.

Let's clarify what happens step-by-step during compile time and runtime for the provided code.


Compile-Time: The Type Check

At compile time, the Java compiler's main job is to ensure that the code is syntactically correct and that method calls are valid based on the reference type. The compiler isn't concerned with the actual object type at this stage; it only looks at the variable's declared type.

  • Animal myAnimal = new Animal();
    • The compiler sees an Animal reference. It checks if the Animal class has a makeSound() method. It finds it, so this line is valid.
  • Animal myDog = new Dog();
    • The compiler sees an Animal reference. It checks if the Animal class has a makeSound() method. It finds it, so this line is also valid. The compiler doesn't care that the actual object is a Dog; it's satisfied that Dog is an Animal (an is-a relationship), and that the makeSound() method exists in the Animal class.
  • myAnimal.makeSound();
    • The compiler sees the myAnimal reference, which is of type Animal. It verifies that the Animal class has a makeSound() method. It finds it, so this call is approved for execution.
  • myDog.makeSound();
    • The compiler sees the myDog reference, which is of type Animal. It verifies that the Animal class has a makeSound() method. It finds it, so this call is also approved for execution. The compiler's work is done. It has confirmed that a makeSound() method exists for both references, and the code is error-free.

Runtime: The Dynamic Dispatch

At runtime, the Java Virtual Machine (JVM) takes over. This is where polymorphism (method overriding) truly comes into play. The JVM uses the actual object type, not the reference type, to decide which method to execute. This process is called dynamic method dispatch.

  • myAnimal.makeSound();
    • The JVM looks at the myAnimal reference and sees that the actual object type is an Animal (new Animal()).
    • It then executes the makeSound() method from the Animal class.
    • Output: The animal makes a sound.
  • myDog.makeSound();
    • The JVM looks at the myDog reference and sees that the actual object type is a Dog (new Dog()).
    • Because the Dog class overrides the makeSound() method, the JVM chooses to execute the makeSound() method from the Dog class.
    • Output: The dog barks.

In summary: The compiler checks validity based on the reference type, but the JVM determines which method to run at runtime based on the actual object type. This is the fundamental difference and the core of runtime polymorphism.

You're asking about two specific scenarios in Java polymorphism, focusing on how the compiler and JVM handle method calls when a method is present in one class but not the other in an inheritance hierarchy. Let's break down each case.


Scenario 1: Method is in Subclass, but NOT in Superclass

class Animal {
    // No makeSound() method here
}

class Dog extends Animal {
    public void makeSound() {
        System.out.println("The dog barks.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        myDog.makeSound(); // This will cause a compilation error
    }
}
Enter fullscreen mode Exit fullscreen mode

What happens?

  • Compile-time: The compiler looks at the reference type, which is Animal. It scans the Animal class for a method named makeSound() with no parameters. It doesn't find one.
  • Because the compiler cannot guarantee that all objects of type Animal (or its subclasses) will have this method, it throws a compilation error.
  • The compiler's job is to ensure the code is safe and valid based on the reference type. If a method doesn't exist in the reference type, it's considered an invalid call. The code will not compile, and therefore, will never reach runtime.

In this case, polymorphism isn't possible because the shared method that enables it (method overriding) doesn't exist in the superclass. A variable of a superclass type can only call methods that are defined in the superclass, even if the actual object is a subclass instance with additional methods.


Scenario 2: Method is in Superclass, but NOT in Subclass

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

class Dog extends Animal {
    // No overridden makeSound() method here
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        myDog.makeSound(); // This will run the method from the Animal class
    }
}
Enter fullscreen mode Exit fullscreen mode

What happens?

  • Compile-time: The compiler looks at the reference type, which is Animal. It finds the makeSound() method in the Animal class and deems the code valid. The code compiles without any errors.
  • Runtime: The JVM takes over. It looks at the myDog variable and sees that the actual object type is a Dog (new Dog()).
  • The JVM then checks the Dog class for an overridden makeSound() method. It doesn't find one.
  • Since there's no overriding method in the Dog class, the JVM automatically "looks up" the inheritance chain to the parent class (Animal) and executes the makeSound() method defined there.
  • Output: The animal makes a sound.

In this second scenario, polymorphism still works as intended. When a method is called on a superclass reference pointing to a subclass object, the JVM first checks the subclass for an overridden version of that method. If it doesn't find one, it uses the implementation from the superclass, which is the default behavior.

here i used gemeni but i will cover this with my own words soon....

Top comments (0)