Writing Methods
A recipe card has a name at the top and steps underneath. Once it's written, "make pancakes" is all anyone needs to say.
Your programs are getting longer. Everything lives inside main, and some chunks show up again and again: printing a divider line, working out an average, formatting a score. When you copy the same lines to three places and then find a mistake in them, you have to fix it three times, and it's easy to miss one.
Methods fix this. A method is a named block of code that you write once and run whenever you want, just by using its name.
Recipe cards
Picture a family recipe box. Each card has a name, like "Grandma's Pancakes," and the steps underneath. When someone says "let's make Grandma's Pancakes," nobody needs to recite the steps. The name is enough, because the steps are written down once, on the card.
A method is a recipe card for your program:
- Declaring a method writes the card: its name and its steps.
- Calling a method says its name, and Java follows the steps.
You've actually been calling methods since your first program. System.out.println(...) is a method someone else wrote. name.length() and Integer.parseInt(...) are methods too. Now you'll write your own.
Your first method
public class Main {
public static void main(String[] args) {
printDivider();
System.out.println("Report Card");
printDivider();
}
static void printDivider() {
System.out.println("====================");
}
}This prints:
====================
Report Card
====================The method printDivider is declared inside the class but outside main. Methods sit side by side in a class, like cards side by side in the box. You can't write one method inside another.
Here's the declaration, piece by piece:
staticmeans the method belongs to the class itself, somaincan call it directly. Every method in this chapter isstatic. You'll find out what the alternative is in static and this.voidmeans the method doesn't give back a result. It just does something.printDivideris the name, followed by parentheses.- The steps go inside the curly braces.
And the call is just the name, the parentheses, and a semicolon: printDivider();.
Now, if you want a longer divider, you change one line and every divider in the program updates.
What happens during a call
When Java reaches a method call, it pauses where it is, jumps to the method, runs its steps from top to bottom, and then comes back to exactly where it left off:
public class Main {
public static void main(String[] args) {
System.out.println("1. Start of main");
sayHello();
System.out.println("3. Back in main");
}
static void sayHello() {
System.out.println("2. Inside sayHello");
}
}1. Start of main
2. Inside sayHello
3. Back in mainIt's like putting a bookmark in a novel to go look something up in a dictionary. You come back to the bookmark afterward.
Giving a method information
A method that always does the same thing is useful, but a method you can customize is much more useful. Put a parameter inside the parentheses, and the caller can hand the method a value:
static void greet(String name) {
System.out.println("Hello, " + name + "!");
}greet("Maria"); // Hello, Maria!
greet("Ben"); // Hello, Ben!name is like a variable that gets its value from whoever calls the method. Parameters and Return Values goes much deeper into this, including methods with several parameters.
Getting a result back
Some methods should work something out and hand the answer back, the way name.length() hands back a number. For that, replace void with the type of the answer, and use return:
static double average(int a, int b, int c) {
return (a + b + c) / 3.0;
}double result = average(88, 94, 83);
System.out.println(result); // 88.33333333333333return does two things: it hands the value back to the caller, and it ends the method immediately. The call average(88, 94, 83) is then replaced by the answer, so you can store it, print it, or use it in a bigger expression.
The type before the name, called the return type, is a promise. double average(...) promises to give back a double. If the method might finish without returning one, the compiler complains:
static double average(int a, int b, int c) {
double result = (a + b + c) / 3.0;
}
// error: missing return statementNaming methods
Methods do things, so name them with verbs, in camelCase, like variables: printDivider, calculateAverage, isPassing, getLetterGrade.
A method that answers a yes-or-no question and returns a boolean reads nicely with is, has, or can:
static boolean isPassing(int score) {
return score >= 75;
}Then if (isPassing(score)) reads almost like an English sentence.
public static void main, decoded
Now you can finally read the line you've been copying since Your First Java Program:
public static void main(String[] args) {mainis a method, and Java calls it for you when your program starts.void: it doesn't return anything.String[] args: it takes one parameter, calledargs.String[]is an array of Strings, the same kind of listsplitgives you in Working with Strings. It holds any extra words typed after the program's name when it starts: runjava Main.java hello world, andargs[0]is"hello"andargs[1]is"world". Most programs, including every one in this track, simply ignore it.static: it belongs to the class, so Java can call it without setting anything up first.public: code outside this class, including Java itself, is allowed to call it.
It's not a magic spell anymore. It's just a method with a very specific name that Java knows to look for.
Why bother?
Splitting a program into methods has real payoffs:
- Less repetition. Write it once, call it everywhere. Fix a bug in one place.
- Readable code.
printReportCard(student)tells you what's happening without making you read 20 lines. - Easier testing. You can check that
averageworks on its own before you use it everywhere.
A good method does one job, and its name says what that job is. If you struggle to name a method without using "and," it's probably doing two jobs and wants to be split.
Try it
This program prints a report card using four small methods. Follow each call to its method and back, and predict the output.
Running Java here
Running Java right in the browser is coming to Syntaxia soon. On your own computer, save this program as Main.java and run it with java Main.java, or use your editor's Run button.
Check your prediction
------------------------
Report card: Maria Santos
------------------------
Average: 88.33333333333333
Letter grade: B
Status: Passed
------------------------printHeader calls printDivider itself, twice. Methods can call other methods. letterGrade returns as soon as one condition matches, so return "F" at the bottom only runs when none of them did.
Try it yourself
- Change the divider to use
=signs instead of-. How many lines of code did you need to change to update all four dividers? - Write a method
static void printStars(int count)that printscountstars on one line, using a loop. Call it frommainwith 5 and then 10. - Write a method
static boolean isHonorRoll(double average)that returnstruefor averages of 90 or above, and use it inmainto print an extra line for honor roll students.
Check your understanding
Up next
You've seen parameters and return values in action. Next, you'll look at them closely: several parameters at once, what happens to a variable you pass in, and how to design a method's inputs and outputs well, in Parameters and Return Values.
