how2examples.com
Home - Introduction to Java Programming

Java Method Overloading

Having more than one method with the same name in a class hierarchy is called overloading. The same method name can be reused (overloaded) as long as the methods have differing argument lists.

Method Matching

When code calls an overloaded method the compiler has to determine which particular version should be invoked. The choice of overloaded method to invoke is straightforward when the overloaded methods have distinctly different argument lists. The choice of overloaded method invoked can be confusing when the methods have the same number of arguments and the types of one version can be cast to the types of another. The following rules determine how the arguments specified in a method call determine which particular version of an overloaded method is invoked:

Contents of OverloadingExample.java:
public class OverloadingExample {
   public static void main(String[] args) {
      // exactly matches x(int, int)
      x(1, 2);
      // exactly matches x(Integer, Integer)
      x(new Integer(1), new Integer(2));
      // even though o1 and o2 are actually instances of Integer,
      // as the method to invoke is decided at compile time
      // x(Object, Object) is invoked
      Object o1 = new Integer(1);
      Object o2 = new Integer(2);
      x(o1, o2);
      // varargs used as only applicable
      x(1);
      // objects unboxed and varargs used as only applicable
      x(new Integer(1), new Integer(2), new Integer(3));
      // char primitives are widened to int primitives and x(int, int) invoked
      x('a', 'b');
      x(1, 2L);
      x(1, 2.0);
      // as Character cannot be unboxed to a char and then widened to a int,
      // x(Object, Object) is invoked instead of x(int, int)
      x(new Character('a'), new Character('b'));
   }
   
   static void x(int i1, int i2) {
      System.out.println("x(int, int)");
   }

   static void x(long i1, long i2) {
      System.out.println("x(long, long)");
   }
   
   static void x(Integer i1, Integer i2) {
      System.out.println("x(Integer, Integer)");
   }

   static void x(Object i1, Object i2) {
      System.out.println("x(Object, Object)");
   }

   static void x(int... i) {
      System.out.println("x(int...)");
   }
}
Command to compile OverloadingExample.java:
javac OverloadingExample.java
Command to run OverloadingExample:
java OverloadingExample
Output from running OverloadingExample:
x(int, int)
x(Integer, Integer)
x(Object, Object)
x(int...)
x(int...)
x(int, int)
x(long, long)
x(Object, Object)
x(Object, Object)

Overloading versus Overriding

Although they both rely on methods in a class hierarchy sharing the same name, overloading is different then the object-orientated concept of method overriding.

Contents of OverloadingAndOverridingExample.java:
public class OverloadingAndOverridingExample {
   public static void main(String[] args) {
      A o = new B();
      // The version of overloadedMethod to use is decided at compile time.
      overloadedMethod(o);
   }
   
   static void overloadedMethod(A o) {
      // The version of overriddenMethod to use is decided at runtime.
      System.out.println("overloadedMethod(A) " + o.overriddenMethod());
   }

   static void overloadedMethod(B o) {
      System.out.println("overloadedMethod(B) " + o.overriddenMethod());
   }
}

class A {
   String overriddenMethod() {
      return "A.overriddenMethod()";
   }
}

class B extends A {
   @Override
   String overriddenMethod() {
      return "B.overriddenMethod()";
   }
}
Command to compile OverloadingAndOverridingExample.java:
javac OverloadingAndOverridingExample.java
Command to run OverloadingAndOverridingExample:
java OverloadingAndOverridingExample
Output from running OverloadingAndOverridingExample:
overloadedMethod(A) B.overriddenMethod()