Topic 3.2
Parameters and Return Values
In one line
Parameters let a method receive input values, and a return value lets it hand one result back to the caller. Together they turn a method into a reusable little machine: values go in, work happens, a result comes out.
Think of it like this
A juice machine. You put fruit in the slot (the arguments), the machine works, and a glass of juice comes out the bottom (the return value). The machine has labelled slots, "apple" and "orange" (the parameters), and it only accepts the right kind of fruit in each slot.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Parameter
- A variable listed in the method header, such as
int x. It receives a value each time the method is called. - Argument
- The actual value given in a call, such as
5insquare(5). It is copied into the matching parameter. - Return value
- The result a method hands back to its caller with
return. The call expression is replaced by this value. - Return type
- The type written before the method name that says what kind of value comes back, or
voidfor nothing. - Signature
- A method's name plus its list of parameter types, such as
square(int). The return type is not part of it. - Widening conversion
- Turning a value into a bigger type that can hold every value of the smaller one, such as
inttodouble. Java does it automatically. - Side effect
- Anything a method does besides returning a value: printing, changing a variable outside itself, writing a file.
- Pure method
- A method whose result depends only on its arguments and that has no side effects. Easy to test and reason about.
Step by step
01Input: parameters
A method with no parameters always does the same thing. Add a parameter and it can work on whatever value the caller chooses.
In static void greet(String name), name is a parameter: a local variable that exists only inside greet. Each call fills it with the argument: greet("Asha") sets name to "Asha" for that call only.
Multiple parameters are separated by commas, and each needs its own type: (int width, int height), never (int width, height).
static void greet(String name, int times) {
for (int i = 0; i < times; i++) {
System.out.println("Hello, " + name);
}
}
// greet("Asha", 2); prints Hello, Asha twice02Output: return values
Replace void with a type, and the method must give back a value of that type with return. The call then becomes that value wherever you wrote it: int area = rectangleArea(3, 4); stores 12.
Because a call is an expression, you can use it anywhere a value fits: inside println, inside arithmetic, or as an argument to another call: square(square(2)) is 16.
return does two things at once: it sets the result and it ends the method immediately.
static int rectangleArea(int width, int height) {
return width * height;
}
int a = rectangleArea(3, 4); // 12
System.out.println(rectangleArea(2, 5) + 1); // 1103Every path must return
For a non-void method the compiler checks every route through the body. If any route can reach the closing brace without a return, you get missing return statement.
In the example below, if a > b is false nothing is returned. The compiler doesn't run your code to see whether that can happen; it just checks the structure. Add a final return b; or use if/else with a return in both branches.
static int max(int a, int b) {
if (a > b) {
return a;
}
// error: missing return statement (nothing returned when a <= b)
}04How values are matched and converted
Arguments are matched by position. rectangleArea(3, 4) sets width = 3, height = 4. Swap them and you get a different meaning with no error, which is why methods with many same-typed parameters are risky.
Each argument must be assignable to its parameter type. An int fits into a double parameter (widened to 7.0). A double into an int parameter fails with incompatible types: possible lossy conversion from double to int. Cast explicitly, square((int) 2.5), if you really want to drop the fraction.
The same rule applies to return: in a method returning double, return 7; is fine (widened); in a method returning int, return 7.5; is a compile error.
05Order of evaluation is left to right
Before the body runs, Java evaluates each argument expression, from left to right, and only then copies the values into the parameters. JLS section 15.7.4 guarantees this order; in C it's unspecified.
This matters when arguments have side effects, such as a method that prints, or i++. With int i = 1; f(i++, i++); the method receives 1 and 2, always.
06What the bytecode shows
Parameters are just the first local variables of the method's frame. In add(int a, int b), a is local slot 0 and b is slot 1. The caller pushes the argument values, invokestatic creates the new frame with those values in slots 0 and 1, and ireturn hands the top value back.
The descriptor (II)I reads: two int parameters, returns int.
07Returning more than one value
A method can only return one thing. When you need two results (say the smallest and largest number in a list), return a container holding both: an array now, and a record once you reach Topic 4.9 (record MinMax(int min, int max)), which is clearer because each part has a name.
Prefer pure methods where you can: take everything as parameters, return the result, and don't print or change anything else. They're the easiest to test and reuse. Keep printing in main or in methods whose job is printing.
Try it yourself
- 1
Predict, then run
In "Parameters in, result out", change
averageto divide by3instead of3.0. Predict the new average line before running. (It becomes81.0:245 / 3is integer division giving81, then widened todoublefor the return.) - 2
Swap the arguments
Write
static int power(int base, int exp)using a loop. Callpower(2, 10)andpower(10, 2). Both compile, but the results are1024and100: position, not meaning, decides which parameter gets which value. - 3
Trigger a missing return
Write
max(int a, int b)with onlyif (a > b) return a;. Read the compile error, then fix it two ways: with anelse, and with a finalreturn b;.
Code & diagrams
Expected output
area = 12
average = 81.66666666666667
10 even? true
7 even? false
nested = 12Each argument is fully evaluated, in order, before add3 starts.
Expected output
evaluating first
evaluating second
evaluating third
inside add3
sum = 6
inside add3
i++ twice: 3
i is now 3Expected output
half(7) = 3.5
min = 7
max = 42
doneBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Pass a double where an int is expected
Call square(2.5) where square takes an int.
static int square(int x) { return x * x; }
public static void main(String[] args) {
System.out.println(square(2.5));
}Break #2
Forget a return path
Return only inside an if, with nothing after it.
static int max(int a, int b) {
if (a > b) {
return a;
}
}Myth vs fact
Myth
Parameters and arguments are the same thing.
Fact
A parameter is the variable in the declaration. An argument is the value supplied in a call. The argument's value is copied into the parameter.
Myth
The parameter name must match the variable name used by the caller.
Fact
Names are unrelated. square(side) and square(5) both work; only position and type matter.
Myth
A method can return two values with return a, b;.
Fact
That doesn't compile. Return an array, an object or a record that holds both.
Myth
You must use a method's return value.
Fact
You may ignore it. Some tools warn when you ignore results that matter (like String.trim()), because strings are immutable and the result is the only change.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
The return type is not part of a method's Java signature, so you can't overload on return type alone (Topic 3.4). The JVM's descriptor does include it, which is how the compiler can emit *bridge methods* for generics and covariant returns (Topic 8.6).
- ▸
Parameters can be marked
final(static int f(final int x)), which stops reassignment inside the body. It's a readability choice: it doesn't change the caller, and it doesn't appear in bytecode as a constraint on the caller. - ▸
Long parameter lists of the same type (
(int, int, int, int)) are a classic bug source because swapped arguments still compile. Seniors replace them with a parameter object or record, or with a builder (see the System Design course's Builder pattern).
Remember this
- 1
A parameter is a variable declared in the method header, like
int xinstatic int square(int x). An argument is the actual value you pass in the call, like the5insquare(5). When the method starts, each parameter is set to a copy of its argument. - 2
The return type comes before the name:
int,double,boolean,String, an array type, orvoidfor no result. A non-void method must end every possible path withreturn <value>;of a compatible type, or the compiler reportsmissing return statement. - 3
Arguments are matched to parameters by position, not by name: the first argument goes into the first parameter, and so on. Java has no named or default arguments; overloading (Topic 3.4) is the usual substitute for defaults.
- 4
Java checks types at compile time. An
intargument can go into adoubleparameter (a safe widening conversion), but adoublecan't go into anintparameter without an explicit cast, because information might be lost (Topic 1.6). - 5
Arguments are evaluated left to right, fully, before the method body starts. This is guaranteed by the Java Language Specification, so side effects in arguments (like printing) happen in a predictable order.
- 6
A method returns at most one value. To return several, return an array, an object, or (from Java 16) a
record(Topic 4.9). The caller may also ignore a return value:Math.max(1, 2);on its own line compiles and the result is thrown away.
Explain it without notes
What is the difference between a parameter and an argument? Use one example call to show both.
Why does missing return statement appear even when you know the condition is always true at run time?
In what order are method arguments evaluated in Java, and why does it matter?
How would you return both the minimum and maximum of three numbers from one method?
Practice
Write static double celsiusToFahrenheit(double c) (F = C x 9 / 5 + 32) and print the result for 0, 37 and 100.
Write static boolean isLeapYear(int year) (divisible by 4, except centuries, unless divisible by 400) and test 1900, 2000, 2024 and 2023.
Write static int countVowels(String s) that returns how many of a e i o u (lower case) the string contains, and test it on "programming".
Trade-offs
- ↔
Pure methods (inputs in, result out, no printing) are easy to test and reuse, but at some point a program must print or save. Keep the side effects at the edges, in a few clearly named methods.
- ↔
Returning an array for multiple results is quick but unclear (
result[0]means what?). A record costs one line and documents itself. - ↔
Many parameters make a method flexible but easy to call wrongly. Past three or four, consider grouping them into an object.
Done when you can
Done when you can write a method with several parameters and a return value, and use the result.
Done when you can explain parameter vs argument with an example.
Done when you can fix
missing return statementandpossible lossy conversionerrors.Done when you can predict output when arguments have side effects.
Done when you can return two results from one method.