Chapter 6
Methods and recursion
In the last chapters, the method you had to fill in was already in the starter code. Now you write it yourself. A method gives a piece of code a name. You call it as often as you like and only have to write the code once.
Your own methods
A method sits in the class next to main, not inside it. Its header has four parts:
public static double grossPrice(double net)
public static: always goes in front for now. What it means comes in chapter 7.- Return type:
double,int,boolean,String, … orvoidif the method returns nothing. - Name: lower case, says what the method does.
- Parameters: in parentheses, each with a type, separated by commas. When the method is called, they get the values you pass.
return hands back the result and ends the method immediately. You can store the return value, print it or keep calculating with it.
public class Main {
public static double grossPrice(double net) {
return net * 1.19;
}
public static boolean isAdult(int age) {
return age >= 18;
}
public static void printLine(int length) {
for (int i = 0; i < length; i++) {
System.out.print("-");
}
System.out.println();
}
public static void main(String[] args) {
printLine(20);
System.out.printf("Gross: %.2f%n", grossPrice(50.0));
double total = grossPrice(10.0) + grossPrice(20.0);
System.out.printf("Total: %.2f%n", total);
System.out.println("Adult at 17? " + isAdult(17));
printLine(20);
}
}Overloading and varargs
Several methods may have the same name if their parameters differ, in number or type. This is called overloading. When you call it, Java picks the matching one by the arguments. One method may call another, just as max with three parameters uses the one with two.
If a method should take any number of values, put three dots after the type: int... numbers. This is called varargs. Inside the method, numbers is a normal array, an empty one if you pass nothing.
public class Main {
public static int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
public static int max(int a, int b, int c) {
return max(max(a, b), c);
}
public static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
public static void main(String[] args) {
System.out.println(max(3, 7));
System.out.println(max(3, 9, 5));
System.out.println(sum());
System.out.println(sum(4));
System.out.println(sum(1, 2, 3, 4));
}
}Recursion
A method may call itself. This is called recursion and fits when a problem can be reduced to a smaller version of the same problem. Every recursion needs two parts:
- a base case that knows the result directly, e.g.
factorial(1)is1, - a recursive call with a smaller value, e.g.
n * factorial(n - 1).
This is how Java calculates factorial(3): 3 * factorial(2) → 3 * 2 * factorial(1) → 3 * 2 * 1 = 6.
public class Main {
public static void countdown(int n) {
if (n == 0) {
System.out.println("Go!");
return;
}
System.out.println(n);
countdown(n - 1);
}
public static int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
public static void main(String[] args) {
countdown(3);
for (int i = 1; i <= 5; i++) {
System.out.println(i + "! = " + factorial(i));
}
}
}Common mistakes
Method written inside main
A method can't be inside another one. If it's between the braces of
main, the compiler reportsillegal start of expression. Methods sit side by side in the class.return missing in one branch
If a method has a return type, every path through it must end with
return:public static String sign(int n) { if (n > 0) { return "positive"; } else if (n < 0) { return "negative"; } // missing return statement }A
return "zero";at the end fixes the error.Return value thrown away
grossPrice(10.0);on its own does calculate, but the result is lost. Store it (double price = grossPrice(10.0);) or print it. The other way round, a method doesn't print anything just because it has areturn.Parameters are copies
For
int,doubleandboolean, the method gets a copy of the value. If it changes the parameter, the caller doesn't notice. For arrays, however, it gets a reference to the same array (see chapter 4): changes to the elements are visible outside afterwards.Recursion without a stop
If the base case is missing or never reached, the method keeps calling itself until the program stops with
StackOverflowError. Check: does the value get smaller with every call, and does it surely reach the base case?