Course outline · 0% complete

0/29 lessons0%

Course overview →

Overloading, and what static means

lesson 4-2 · ~10 min · 11/29

Overloading

A good name is worth reusing. Callers should write max(...) whatever they are comparing, rather than memorize maxInt, maxDouble, and maxOfThree. The standard library leans on this everywhere, and System.out.println is really about ten methods, one per type it can print.

Java lets several methods share a name as long as their parameter lists differ. This is called overloading, and the compiler picks the right one from the argument types at each call site:

static int max(int a, int b) { ... }
static double max(double a, double b) { ... }
static int max(int a, int b, int c) { ... }

max(3, 9) calls the first, max(2.5, 1.0) the second, and max(1, 7, 5) the third. Python cannot do this, since a second def max simply replaces the first.

Only the parameters count. Two methods differing solely in return type do not compile, because a call like max(3, 9) would give the compiler no way to choose.

Three versions of max

The same name three times, distinguished only by what it accepts.

public class Main {
  static int max(int a, int b) {
    return a > b ? a : b;
  }

  static double max(double a, double b) {
    return a > b ? a : b;
  }

  static int max(int a, int b, int c) {
    return max(max(a, b), c);
  }

  public static void main(String[] args) {
    System.out.println(max(3, 9));
    System.out.println(max(2.5, 1.0));
    System.out.println(max(1, 7, 5));
  }
}

Output

9
2.5
7

The second call prints 2.5 rather than 2, which confirms the double version handled it. Argument types alone decided that, with nothing at the call site saying which overload was wanted.

The three-argument version delegates to the two-argument one twice, max(max(1, 7), 5). Reusing a working overload instead of rewriting the comparison is the usual pattern, since there is then one place where the logic can be wrong.

static and instance, a first look

That a > b ? a : b is the ternary operator: a condition, then ?, then the value if true, then :, then the value if false. It is Python's a if a > b else b.

Now for static. A static method belongs to the class itself, so you call it directly, as in Math.sqrt(2.0) or the square(6) from the previous lesson. An instance method belongs to one particular object, so word.length() from lesson 2-2 needs a String object to act on.

KindBelongs toCalled as
staticthe classMath.sqrt(2.0)
instanceone objectword.length()

Unit 5 is where you build objects of your own and write instance methods for them.

This is also enough to decode lesson 1-1's starting line, public static void main(String[] args): usable from outside the class with public, belonging to the class with static, returning nothing with void, and taking an array of Strings holding the command-line arguments.

Which overloads can coexist

static int f(int x) and static int f(String s) can legally live in one class.

Overloads must differ in parameter types, and int against String is a real difference, so the compiler can always tell which one a call meant.

PairLegal
int f(int) and int f(String)yes, parameter types differ
int f(int) and double f(int)no, only the return type differs
int f(int x) and int f(int y)no, only the parameter name differs

The last two fail for the same reason. A call written f(3) carries no information about the return type or the parameter name, so there would be nothing to select on.

One name, three parameter types

Three overloads of describe, each labeling its argument differently.

public class Main {
  static void describe(int n) {
    System.out.println("int: " + n);
  }

  static void describe(String s) {
    System.out.println("text: " + s);
  }

  static void describe(boolean b) {
    System.out.println("flag: " + b);
  }

  public static void main(String[] args) {
    describe(42);
    describe("hi");
    describe(true);
  }
}

Output

int: 42
text: hi
flag: true

Each overload prints and hands nothing back, so all three have the return type void. The parameter types int, String, and boolean are the only thing distinguishing them.

Every call site reads identically, which is the value of overloading. A reader sees describe(x) and does not need to know or care which of the three bodies will run.