Parameters and Return Values
A photocopier takes in a sheet of paper and hands back copies. What you feed it, and what comes out, is everything you need to know to use it.
In Writing Methods, you wrote methods that took a value in and methods that handed a value back. This lesson slows down and looks at both ends closely: how to pass several values, what exactly the method receives, and how to design a method whose inputs and outputs make sense.
A machine with a slot and a tray
Think of a method as a machine on a counter. There's a slot on one side where you feed things in, and a tray on the other side where the result comes out.
- The parameters are the slot. They say what the machine needs, and what type each thing must be.
- The return value is the tray. It says what the machine gives back.
You don't need to know how the machine works inside. As long as you know what goes in the slot and what comes out of the tray, you can use it.
Parameters and arguments
Two words that sound alike, and mean slightly different things:
static int add(int a, int b) { // a and b are parameters
return a + b;
}
int sum = add(5, 3); // 5 and 3 are arguments- Parameters are the variables listed in the method's declaration:
int a, int b. Each one has a type and a name. - Arguments are the actual values you pass in when you call the method:
5and3.
When the method is called, each argument is copied into its matching parameter, in order. a gets 5, and b gets 3.
People mix these two words up all the time, and nobody will be confused if you do. But knowing the difference helps you read error messages, which use them precisely.
Several parameters
Separate parameters with commas. Each one needs its own type, even if they're all the same type:
static void printScore(String name, int score, int maxScore) {
System.out.println(name + ": " + score + " / " + maxScore);
}printScore("Maria", 47, 50); // Maria: 47 / 50Arguments are matched to parameters by position, not by name. "Maria" goes into name because it's first. Mix up the order, and Java either complains about the types or, worse, quietly uses the wrong values:
printScore("Maria", 50, 47); // Maria: 50 / 47 (oops)Both numbers are int, so Java can't tell they're backwards. With parameters of the same type, double-check the order.
And the number of arguments must match exactly:
printScore("Maria", 47);
// error: method printScore in class Main cannot be applied to given types;Java passes a copy
Here's something that surprises people. What does this print?
public class Main {
public static void main(String[] args) {
int score = 70;
addBonus(score);
System.out.println(score);
}
static void addBonus(int points) {
points = points + 10;
}
}70Not 80. Here's why: when you call addBonus(score), Java doesn't hand over the score variable itself. It copies the value 70 into the parameter points. The method changes its own copy, and the copy disappears when the method ends. The original score in main is never touched.
This is called pass by value, and Java always works this way. It's like giving someone a photocopy of your homework. They can scribble all over the copy, and your original stays clean.
If you want the change to stick, have the method return the new value, and store it:
static int addBonus(int points) {
return points + 10;
}int score = 70;
score = addBonus(score);
System.out.println(score); // 80(You'll see in Arrays that passing an array or other object works a little differently: the copy is a copy of directions to the object, so a method can change the object those directions lead to. For numbers, booleans, and chars, what you've learned here is the whole story.)
More about return
A method with a return type must return a value of that type, on every possible path through the method. The compiler checks this:
static String passOrFail(int score) {
if (score >= 75) {
return "Pass";
}
}
// error: missing return statementWhat if the score is below 75? The method would reach the end without returning anything, so Java refuses. Add a return for the other case.
Because return ends the method immediately, you can use it to leave early. This is called an early return, and it often makes code simpler than a deep if-else:
static String letterGrade(int score) {
if (score < 0 || score > 100) {
return "Invalid";
}
if (score >= 90) {
return "A";
}
if (score >= 80) {
return "B";
}
return "C or below";
}A void method can use return; on its own, with no value, to stop early:
static void printIfPassing(String name, int score) {
if (score < 75) {
return;
}
System.out.println(name + " passed!");
}Using return values
A method call that returns a value can go anywhere that value could go. You can store it, print it, compare it, or even pass it straight into another method:
double avg = average(88, 94, 83);
System.out.println(average(88, 94, 83));
if (average(88, 94, 83) >= 75) { ... }
System.out.println(letterGrade((int) average(88, 94, 83)));One mistake to watch for: calling a method that returns a value and then ignoring it. average(88, 94, 83); on a line by itself compiles fine, but the answer is thrown away, exactly like name.toUpperCase(); in Working with Strings.
Designing good methods
A well-designed method is easy to use correctly. A few habits help:
- Take in what you need, nothing more. A method that calculates an average needs the scores, not the student's name.
- Return results instead of printing them, when the caller might want to do something else with the answer. A method that returns an average can be printed, stored, or compared. A method that only prints it can't be used any other way.
- Keep the parameter list short. Three or four parameters is plenty. If you need seven, it's a sign that some of them belong together in an object, which you'll learn to build in Classes and Objects.
- Give parameters clear names.
calculateTotal(double price, int quantity)explains itself.calculateTotal(double p, int q)doesn't.
Try it
This program runs a small cafeteria checkout. Watch which methods return values, which ones just print, and what happens to budget when it's passed to a method. Predict the output.
%-10s pads the label to 10 characters, lined up on the left, and %7.2f prints the amount 7 characters wide with 2 decimal places. The line with ? and : is the ternary operator from Operators and Expressions: it picks one of the two messages.
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
Adobo x2 130.00
Juice x3 60.00
Total 190.00
Budget after spend(): 200.0
Budget after remaining(): 10.0
No more adobo today.spend only changed its own copy of the budget, so budget in main was still 200.0 afterward. remaining returned the new value, and main stored it, so that change stuck.
Try it yourself
- Add a third item, rice at 15 pesos, quantity 2, and include it in the total. Does the last line change?
- Delete the
spendmethod and the lines that call and print it. Why was it useless? - Write a method
static double applyDiscount(double amount, double percent)that returns the amount after a discount. Use it to take 10 percent off the total before it's subtracted from the budget.
Check your understanding
Up next
What if you want add to work with two numbers, and also with three? Or with decimals as well as whole numbers? Java lets several methods share one name, as long as their parameters differ. That's Method Overloading.
