Overloading Examples

Java Method Overloading Output Questions with Answers | Tricky Java Programs

Java Method Overloading Output Questions with Answers

Method overloading is one of the most frequently asked topics in Java interviews — and one of the trickiest to master. 🎯

In this post, you'll work through 23 output-based questions on method overloading that test your understanding of:

  • Widening — byte → short → int → long → float → double
  • Boxing & autoboxing — int → Integer, double → Double
  • Varargs — int... i parameter rules
  • Reference type resolution — the most specific method wins
  • Ambiguity errors — when the compiler cannot decide

How to use: Read each question, decide the output in your head, then click Show Answer to verify. Don't run the code first — that's cheating! 😄

💡 Important: Many of these questions produce compilation errors, not output. Distinguishing between compile errors, runtime exceptions, and outputs is exactly what interviewers want to see.

Questions 1–5: Primitive Widening & Boxing

Question 1

What is the output?

public class A {

    void add(int i) {
        System.out.println("hi");
    }

    void add(byte i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1);
    }
}
✅ Show Answer

Output: hi

Literal 1 is an int. Exact match with add(int) wins over widening to add(byte).

Question 2

What is the output?

public class A {

    void add(float i) {
        System.out.println("hi");
    }

    void add(byte i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1);
    }
}
✅ Show Answer

Output: hello

add(int) is absent. Java prefers widening over boxing — but between byte and float, both are widenings. Java chooses the most specific — byte is "closer" to int than float.

Question 3

What is the output?

public class A {

    void add(Double i) {
        System.out.println("hi");
    }

    void add(byte i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1);
    }
}
✅ Show Answer

Output: hello

Widening (int → byte) is preferred over boxing + widening (int → Double requires boxing first then widening to double). Java avoids boxing when a widening match is available.

Question 4

What is the output?

public class A {

    void add(Float i) {
        System.out.println("hi");
    }

    void add(byte i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1.0);
    }
}
✅ Show Answer

Compilation Error. 1.0 is a double literal. add(Float) requires boxing+widening, but a double cannot be narrowed to Float implicitly, and 1.0 is not compatible with byte.

Question 5

What is the output?

public class A {

    void add(Double i) {
        System.out.println("hi");
    }

    void add(byte i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1.0f);
    }
}
✅ Show Answer

Output: hi

1.0f is a float. It cannot be narrowed to byte. Boxing + widening: float → Float → Double? No — Java boxes float to Float, then widens to Double via a boxing then widening reference conversion. Double is the only compatible match.

Questions 6–11: Varargs vs Fixed Arguments

Question 6

What is the output?

public class A {

    void add(int[] i) {
        System.out.println("hi");
    }

    void add(int ...i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1);
    }
}
✅ Show Answer

Output: hello

add(int...) is the only applicable method. add(int[]) requires passing an array explicitly — not a single int.

Question 7

What is the output?

public class A {

    void add(int i) {
        System.out.println("hi");
    }

    void add(int ...i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1);
    }
}
✅ Show Answer

Output: hi

Fixed-argument method add(int) is always preferred over varargs when the argument matches exactly.

Question 8

What is the output?

public class A {

    void add(int i) {
        System.out.println("hi");
    }

    void add(int ...i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add();
    }
}
✅ Show Answer

Output: hello

No fixed-argument method can accept zero arguments. Varargs can accept zero or more — so add(int...) is chosen.

Question 9

What is the output?

public class A {

    void add(int i) {
        System.out.println("hi");
    }

    void add(int ...i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1, 2);
    }
}
✅ Show Answer

Output: hello

Two arguments don't match add(int). Only varargs accepts them.

Question 10

What is the output?

public class A {

    void add(int i, float j) {
        System.out.println("hi");
    }

    void add(int ...i, float j) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1, 2);
    }
}
✅ Show Answer

Compilation Error. In Java, varargs must be the last parameter. void add(int ...i, float j) is invalid syntax and will not compile.

Question 11

What is the output?

public class A {

    void add(int i, float j) {
        System.out.println("hi");
    }

    void add(float j, int ...i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1, 2);
    }
}
✅ Show Answer

Output: hello

Step 1: add(int, float) — first arg matches int, second is int 2 which can widen to float. Step 2: add(float, int...) — first arg widens to float, second becomes vararg.

Phase rule: Java tries fixed-arity first (Phase 1), then varargs (Phase 3). Phase 1 fails because add(int, float) needs both args to be fixed — but wait, it does match!

Actually: Compilation Error — Ambiguous. Both methods are applicable in Phase 3 (varargs considered). Java resolves varargs via specific rules and this particular combination triggers ambiguity in some compilers. The safest answer is a compile-time ambiguity error.

Questions 12–14: Ambiguity Between Overloads

Question 12

What is the output?

public class A {

    void add(int i, float j) {
        System.out.println("hi");
    }

    void add(float j, int i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1, 2);
    }
}
✅ Show Answer

Compilation Error — Ambiguous method call.

Both methods are equally applicable via widening (int → float for one arg). The compiler cannot decide which is more specific.

Question 13

What is the output?

public class A {

    void add(int i, float j) {
        System.out.println("hi");
    }

    void add(float j, int i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1, 2.6);
    }
}
✅ Show Answer

Compilation Error — Ambiguous method call.

2.6 is a double. Neither method has a double parameter. add(int, float) requires narrowing double → float (not allowed implicitly). add(float, int) requires widening int → float and narrowing double → int (not allowed).

Neither is applicable → no suitable method found (which is often reported as an ambiguity or “cannot find symbol” error).

Question 14

What is the output?

public class A {

    void add(int i, float j) {
        System.out.println("hi");
    }

    void add(float j, int i) {
        System.out.println("hello");
    }

    public static void main(String[] args) {
        A a = new A();
        a.add(1, 2.6f);
    }
}
✅ Show Answer

Output: hi

2.6f is a float. Now add(int, float) matches exactly — no ambiguity. The first method is chosen.

Questions 15–20: null, Reference Types & Method Resolution

Question 15

What is the output?

public class A {

    public static void main(String[] args) {
        System.out.println(null);
    }
}
✅ Show Answer

Compilation Error — Ambiguous method call.

System.out.println is heavily overloaded (String, char[], Object, etc.). Passing null makes the call ambiguous because multiple overloads accept null.

Question 16

What is the output?

class Animal {}

class Dog extends Animal {}

public class A {
    void show(Dog d) {
        System.out.println("hi");
    }

    void show(Animal d) {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        Animal a = new Dog();
        new A().show(a);
    }
}
✅ Show Answer

Output: Hello

Overloading is resolved at compile time based on the reference type. a is declared as Animal — so show(Animal) is chosen.

Question 17

What is the output?

class Animal {}

class Dog extends Animal {}

public class A {
    void show(Dog d) {
        System.out.println("hi");
    }

    void show(Animal d) {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        Dog a = new Dog();
        new A().show(a);
    }
}
✅ Show Answer

Output: hi

Reference type is Dog — the most specific match show(Dog) is chosen.

Question 18

What is the output?

class Animal {}

class Dog extends Animal {}

public class A {
    void show(Dog d) {
        System.out.println("hi");
    }

    void show(Animal d) {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        new A().show(null);
    }
}
✅ Show Answer

Output: hi

When null is passed, Java picks the most specific reference type. Dog is more specific than Animal, so show(Dog) is selected.

Question 19

What is the output?

class Animal {}

class Dog extends Animal {}

public class A {
    void show(Dog d) {
        System.out.println("hi");
    }

    void show(Animal d) {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        Dog d = null;
        new A().show(d);
    }
}
✅ Show Answer

Output: hi

Reference type is Dog. The method chosen is show(Dog) based on static type, not runtime value.

Question 20

What is the output?

class Animal {}

class Dog extends Animal {}

public class A {
    void show(Dog d) {
        System.out.println("hi");
    }

    void show(Animal d) {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        Animal d = null;
        new A().show(d);
    }
}
✅ Show Answer

Output: Hello

Reference type is Animal. Method chosen is show(Animal).

Questions 21–23: Advanced Ambiguity & Return Types

Question 21

What is the output?

class Animal {}

class Dog extends Animal {}

class Donkey extends Animal {}

public class A {
    void show(Dog d) {
        System.out.println("hi");
    }

    void show(Donkey d) {
        System.out.println("hi d");
    }

    void show(Animal d) {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        new A().show(null);
    }
}
✅ Show Answer

Compilation Error — Ambiguous method call.

Dog and Donkey are unrelated siblings under Animal. Neither is more specific than the other. The compiler cannot pick one → ambiguity.

Question 22

What is the output?

class Person {}

class Student extends Person {}

class Animal {}

class Dog extends Animal {}

public class A {
    void show(Person d) {
        System.out.println("hi");
    }

    void show(Student d) {
        System.out.println("hi student");
    }

    void show(Animal d) {
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        new A().show(null);
    }
}
✅ Show Answer

Compilation Error — Ambiguous method call.

Person and Animal are unrelated. Student is more specific than Person, but there is no relationship between Student and Animal. The compiler cannot rank them → ambiguity.

Question 23

What is the output?

public class A {
    int show(int d) {
        return d;
    }

    double show(double d) {
        return d;
    }

    public static void main(String[] args) {
        System.out.println(new A().show(12.));
    }
}
✅ Show Answer

Output: 12.0

12. is a double literal. The most specific match is show(double), which returns 12.0. Note: overloaded methods may differ only by return type not — here the parameter types differ (int vs double), which is valid overloading.

Final Thoughts

Congratulations on completing all 23 questions! 🎉

Method overloading questions test something subtle: they force you to know Java's method resolution rules in exact order. If you can answer these confidently, you're ready for real interview questions on overloading.

🔑 Key Rules to Remember

  1. Phase 1 — Widening: Exact match first, then primitive widening (byte → short → int → long → float → double).
  2. Phase 2 — Boxing/Unboxing: Used only if no widening match is available.
  3. Phase 3 — Varargs: The last resort, only if no fixed-arity method applies.
  4. Most specific reference wins: When passing null or an object, the most specific reference type is chosen.
  5. Ambiguity → compile error: If two overloads are equally applicable and unrelated, the compiler refuses to guess.
  6. Varargs must be last: void m(int... a, float b) is illegal.
  7. Return type doesn't disambiguate: You cannot overload only by return type.

📚 Practice More

Try to modify these programs and predict new outputs. The more you practice, the sharper your Java intuition becomes.

Want the next level? Check out:

  • Java 8 Stream API interview questions
  • Java collections output-based questions
  • Multithreading tricky programs
  • Exception handling output questions

If this post helped you, share it with a friend preparing for interviews!

No comments: