Table of contents
1.
Introduction
2.
What is Compile Time Polymorphism?
2.1.
Java
3.
What is Run Time Polymorphism?
3.1.
Java
4.
Difference Between Compile-time and Run-time Polymorphism in Java
5.
When to Use Which Type of Polymorphism
5.1.
Compile Time Polymorphism (Method Overloading)
5.2.
Run Time Polymorphism (Method Overriding)
6.
Frequently Asked Questions
6.1.
Can we override static methods?
6.2.
Is operator overloading supported in Java?
6.3.
How does run-time polymorphism benefit code reusability?
7.
Conclusion
Last Updated: Jul 3, 2025
Easy

Difference Between Compile Time and Run Time Polymorphism in Java

Author Gaurav Gandhi
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Polymorphism is a fundamental concept in object-oriented programming that allows objects of different types to be treated as objects of a common superclass. In Java, polymorphism is achieved through method overriding and method overloading, which can occur either at compile time or run time.

Compile Time and Run Time Polymorphism

What is Compile Time Polymorphism?

Compile-time polymorphism, also known as static polymorphism, hinges on the concept of method overloading & operator overloading within a class. It's determined during the compilation phase, which means the compiler knows which function to invoke. This can significantly enhance performance, as the decision-making process is squared away before runtime.

Consider a scenario in a coding environment where we have a class Calculator that can perform operations like addition & multiplication. However, these operations might need to cater to different data types or a varying number of operands. This is where method overloading comes into play, allowing multiple methods with the same name but different parameters within the same class.

  • Java

Java

class Calculator {
// Method to add two integers
int add(int a, int b) {
return a + b;
}

// Overloaded method to add three integers
int add(int a, int b, int c) {
return a + b + c;
}

// Overloaded method to add two double values
double add(double a, double b) {
return a + b;
}
}

public class Main {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println("Sum of two integers: " + calc.add(5, 7));
System.out.println("Sum of three integers: " + calc.add(4, 5, 6));
System.out.println("Sum of two doubles: " + calc.add(2.5, 3.5));
}
}
You can also try this code with Online Java Compiler
Run Code

Output

Output

In the above example, the Calculator class demonstrates compile-time polymorphism through method overloading. Depending on the parameters passed to the add method, the compiler determines which version of the method to call during compilation.

What is Run Time Polymorphism?

Run-time polymorphism, or dynamic polymorphism, is all about method overriding. Unlike its compile-time counterpart, decisions about which method to invoke are made at runtime. This polymorphism is closely tied to inheritance & the use of base class references to point to subclass objects.

To illustrate, let's consider a basic example involving a superclass Animal and its subclasses Dog & Cat. Each subclass has its own implementation of the makeSound method.

  • Java

Java

class Animal {
void makeSound() {
System.out.println("Some generic animal sound");
}
}

class Dog extends Animal {
void makeSound() {
System.out.println("Bark");
}
}

class Cat extends Animal {
void makeSound() {
System.out.println("Meow");
}
}

public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
Animal myDog = new Dog();
Animal myCat = new Cat();

myAnimal.makeSound(); // Outputs "Some generic animal sound"
myDog.makeSound(); // Outputs "Bark"
myCat.makeSound(); // Outputs "Meow"
}
}
You can also try this code with Online Java Compiler
Run Code


Output

Output

This code is an example of run-time polymorphism where the actual method called is determined at runtime based on the object type, not the reference type.

Difference Between Compile-time and Run-time Polymorphism in Java

When discussing compile-time and run-time polymorphism, it's helpful to lay out their differences in a comparison table. This can clarify the distinct characteristics and use cases for each type.

Let's understand ​​Compile-time vs Run-time Polymorphism in Java in the comparison table 

FeatureCompile-Time PolymorphismRun-Time Polymorphism
DefinitionPolymorphism resolved during compiler time is known as compile-time polymorphism. It's mainly achieved through method overloading and operator overloading.Polymorphism that is resolved during runtime is known as run-time polymorphism. It's commonly implemented through method overriding using inheritance and interfaces.
MechanismUses method overloading and operator overloading.Employs method overriding through inheritance or interfaces.
BindingStatic binding - method call is bound to the method body at compile time.Dynamic binding - method call is bound to the method body at runtime.
FlexibilityLess flexible as the method call is decided at compile time.More flexible as the method call can be determined at runtime.
PerformanceFaster, as the method execution path is known at compile time.Slightly slower due to the overhead of determining the method execution path at runtime.
ExampleOverloading a print() method to work with different data types.Overriding a draw() method in a superclass and providing different implementations in subclasses.

When to Use Which Type of Polymorphism

Understanding when to use polymorphism in Java is key to writing clean, maintainable, and efficient code. Let’s look at two main types—compile time polymorphism and run time polymorphism—and when to choose each in real-world scenarios.

Compile Time Polymorphism (Method Overloading)

Use When: You need performance, predictability, or better readability in your code.

Compile time polymorphism occurs when multiple methods in the same class share the same name but differ in parameters (method overloading). It’s resolved by the compiler, making it faster and more predictable.

Ideal for:

  • Utility/helper classes (e.g., math, formatting)
  • Input validation
  • Logging with varying details

Example:

public class Formatter {
    public String format(String text) {
        return text.trim();
    }

    public String format(String text, int width) {
        return String.format("%-" + width + "s", text);
    }
}

In this example, the right method is chosen during compile time, making the logic clear and optimized.

Choose compile time polymorphism when:

  • You don’t need dynamic behavior.
  • Code readability and performance matter more than flexibility.
  • You want to handle different input variations cleanly.

Run Time Polymorphism (Method Overriding)

Use When: You need flexibility, extensibility, or interface-driven design.

Run time polymorphism happens when a subclass overrides a method from a superclass or interface. It’s resolved during execution, allowing different behaviors for different object types—even if referenced as a common type.

Ideal for:

  • GUI event handling
  • Extending API behavior
  • Strategy pattern implementations

Example:

interface Notification {
    void send(String message);
}

class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

// At runtime Notification notifier = getNotifierBasedOnUserPreference();
notifier.send("Hello!");

Here, getNotifierBasedOnUserPreference() could return different implementations. The method send() is decided at run time, offering flexibility.

Choose run time polymorphism when:

  • Your code must work with interfaces or abstract classes.
  • You need different behaviors depending on the object type at runtime.
  • You're building extensible, scalable systems.

Frequently Asked Questions

Can we override static methods?

No, static methods cannot be overridden. They are bound to the class, not to the instance of the class.

Is operator overloading supported in Java?

Java does not support operator overloading, except for the string concatenation operator (+), which is overloaded by the Java compiler.

How does run-time polymorphism benefit code reusability?

Run-time polymorphism allows for defining a common interface for different implementations, enabling the same code to work with objects of different classes, thus enhancing reusability.

Conclusion

Polymorphism is like a superpower in coding that lets us use the same piece of code in different ways. With compile-time polymorphism, we decide beforehand how we're going to use this superpower, making our code run fast because everything is set in stone from the start. But with run-time polymorphism, we get to make those decisions while the code is running, giving us the flexibility to adapt on the fly. This makes our code smart enough to handle different situations without needing a bunch of extra instructions. So, whether you're just starting out in coding or you're working on a big project, understanding how to use both types of polymorphism will help you write better, more efficient code that can do more with less.

Live masterclass