Fundamentals 10 min read

Method Overloading vs Overriding in Java: Key Differences and Common Pitfalls

This article explains Java's two polymorphism mechanisms—static overload and dynamic override—detailing definitions, compiler rules, valid code examples, a side‑by‑side comparison table, and frequent pitfalls such as static method hiding, access‑modifier changes, and exception widening.

Java Tech Workshop
Java Tech Workshop
Java Tech Workshop
Method Overloading vs Overriding in Java: Key Differences and Common Pitfalls

Java’s Two Polymorphism Mechanisms

Static (compile‑time) polymorphism is achieved through method overloading, while dynamic (run‑time) polymorphism is realized by method overriding.

Method Overload (Overload)

Official definition

In the same class, multiple methods can share the same name but must have different parameter lists.

Conditions that trigger overload

Different number of parameters

Different parameter types

Different order of parameter types

Valid overload examples

public class OverloadDemo {
    // basic method
    public void test(int a) { System.out.println("参数为int类型"); }

    // overload 1: different number of parameters
    public void test(int a, int b) {}

    // overload 2: different parameter type
    public void test(String a) {}

    // overload 3: different order (different types)
    public void test(int a, String b) {}
    public void test(String b, int a) {}
}

Four items that do NOT affect overload resolution

Return type, access modifier, declared exceptions, and method modifiers are ignored; changing any of them alone does not create a new overload and will cause a compile‑time error.

// error: only return type differs
public void demo() {}
public int demo() { return 1; }

// error: only access modifier differs
public void func() {}
private void func() {}

Compilation‑time mechanism

The compiler builds a unique method signature from the method name and parameter list; the binding is fixed at compile time, so the called method cannot change at runtime.

Method Override (Override)

Official definition

In a subclass, an instance method that is non‑private, non‑static, and non‑final can be reimplemented with the same signature as the superclass method.

Five mandatory rules

Method name and parameter list must be identical to the superclass method.

Access level in the subclass must be at least as permissive as in the superclass.

Return type may be covariant (subclass type for reference types).

Checked exceptions thrown by the subclass method must be the same or narrower.

Methods that are private, static, final, or constructors cannot be overridden.

Valid override examples

class Person {}
class Student extends Person {}

class Father {
    public Person getInfo() { return new Person(); }
    public void say() throws Exception {}
}

class Son extends Father {
    // covariant return
    @Override
    public Student getInfo() { return new Student(); }

    // narrower exception
    @Override
    public void say() throws RuntimeException {}
}

Dynamic binding

At runtime the JVM uses the virtual method table (vtable) to locate the overridden method based on the actual object type.

Common Pitfalls

1. Static methods “look like” overrides but are actually hidden

class Father { public static void show() { System.out.println("父类静态方法"); } }
class Son extends Father { public static void show() { System.out.println("子类静态方法"); } }
class Test { public static void main(String[] args) {
    Father f = new Son();
    f.show(); // prints "父类静态方法"
} }

Static methods belong to the class, are bound at compile time, and do not participate in polymorphism.

2. Different parameter type = overload, not override

class Father { public void test(Object obj) {} }
class Son extends Father {
    // not an override – overload
    public void test(String str) {}
}

Use @Override to let the compiler verify correct overriding.

3. Private methods cannot be overridden

class Father { private void test() { System.out.println("父类私有方法"); } }
class Son extends Father { public void test() { System.out.println("子类方法"); } }

The subclass method is a new method, unrelated to the superclass private method.

4. Reducing access level causes a compile‑time error

Subclass access cannot be more restrictive than the superclass (public > protected > package‑private > private).

5. Widening checked exceptions breaks overriding

The subclass method may throw the same or a narrower checked exception, never a broader one.

6. Varargs and array parameters conflict

// compile error: both signatures are considered the same
public void fun(int[] arr) {}
public void fun(int... arr) {}

7. Changing only the parameter name does not create an overload

Overload resolution ignores parameter names.

@Override Annotation

Forces the compiler to check that the method truly overrides a superclass method.

Prevents mistakes such as wrong parameter types, return types, static hiding, or incorrect access modifiers.

Improves code readability by clearly marking overridden methods.

Development guideline: always add @Override to overridden methods.

Conclusion

Overloading provides compile‑time static polymorphism within a single class, enabling flexible method signatures. Overriding enables run‑time dynamic polymorphism across inheritance hierarchies, allowing subclasses to customize behavior. Remember: overload = different parameters; override = inheritance; overload is bound at compile time; override is resolved at runtime.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaCompilationRuntimepolymorphism@OverrideMethod OverloadingMethod Overriding
Java Tech Workshop
Written by

Java Tech Workshop

Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.