beginner19 min

Methods: Parameters, Return Values, and Overloading

How Java methods pass data in and out, and how the compiler picks the right method when several share a name but differ in parameters.

What you'll learn

  • Design a method's signature (parameters and return type) to match a stated requirement
  • Explain that Java is always pass-by-value, even for reference types
  • Predict which overload the compiler selects for a given call

Prerequisites

Explanation

A Java method's signature is its name plus the number, order, and types of its parameters (the return type is not part of the signature for overload-resolution purposes, though it must still be declared). Java is always pass-by-value — this surprises people who expect object arguments to be "passed by reference" because they can mutate the object's fields through the parameter. What's actually happening: for a reference-type parameter, the value being copied is the reference itself, not the object. The method gets its own copy of that reference, pointing at the same object — so mutating fields through it is visible to the caller, but reassigning the parameter to point at a different object inside the method has no effect on the caller's variable, because that reassignment only changes the method's local copy of the reference.

Method overloading lets several methods share one name as long as their parameter lists differ (in count, order, or types) — the compiler picks the correct one at compile time based on the arguments at each call site. print(String s) and print(int n) can coexist; print("hi") calls the first, print(5) calls the second. Overload resolution has a real, sometimes-surprising set of rules: Java prefers an exact type match first, then a match reachable by a widening primitive conversion (an int argument can match a long parameter if no int overload exists), and only as a last resort does it consider autoboxing (int to Integer) or varargs. This means adding a new overload to existing code can occasionally change which overload an existing call resolves to — a real, if rare, source of surprising behavior when a codebase's overload set changes.

Two methods that differ only in return type are not valid overloads — the compiler rejects that as ambiguous, because a call site like foo(); gives the compiler no information to disambiguate on. And a method's parameters are themselves local variables scoped to that method — reassigning a parameter inside a method body never affects the variable the caller passed in, whether that parameter is a primitive or a reference.

Example

Pass-by-value-of-the-reference, modeled in JS (which has the exact same semantics as Java here): mutating fields is visible to the caller, reassigning the parameter is not.

function mutateField(obj) {
  obj.x = 999; // visible to the caller -- same object
}
function reassignParameter(obj) {
  obj = { x: -1 }; // only changes the LOCAL copy of the reference
}

const point = { x: 1 };
mutateField(point);
console.log(point.x); // 999 -- the caller's object was mutated

reassignParameter(point);
console.log(point.x); // still 999 -- reassigning the parameter didn't touch the caller's variable

Try it yourself

Add a second field y to point and mutate it inside mutateField -- confirm it's visible after the call.

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Guided exercise

Guided exercise

Write resolveOverload(argType) modeling Java overload resolution among print(String), print(int), and print(double). Return 'String' for a 'string' argType, 'int' for 'int', and 'double' for 'double' or 'float' (float widens to double when no float overload exists).

Checks: string resolves to print(String) · int resolves to print(int) · float widens to print(double)

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Independent exercise

Independent exercise

Write applyDiscount(price, percentOff) that returns a NEW discounted price without mutating any external state (model Java's pass-by-value: the function must be pure, taking primitives in and returning a new primitive out).

Checks: 20% off 100 is 80 · 0% off leaves the price unchanged · 50% off 200 is 100

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Common mistakes

  • Expecting `void reset(Point p) { p = new Point(0, 0); }` to change the caller's variable -- it only reassigns the local parameter, never the caller's reference.
  • Trying to overload two methods that differ only in return type -- the compiler rejects this; overloading requires a difference in the parameter list.
  • Assuming the most 'specific-looking' overload always wins -- Java's actual resolution order (exact match, then widening, then autoboxing, then varargs) can pick a different overload than intuition suggests when types are close.

Knowledge check

Knowledge check

1. A method `void rename(Person p) { p = new Person("New Name"); }` is called as `rename(alice)`. What happens to alice afterward?
2. Which pair of methods is a VALID overload of each other?
3. Why is Java described as 'always pass-by-value', even though mutating an object's fields through a method parameter is visible to the caller?

Takeaway

Java always copies the argument's value into the parameter — for objects, that value is the reference, which is why mutating fields is visible to the caller but reassigning the parameter is not. Overloads must differ in their parameter list, never only in return type.

Summary

A method's signature is its name plus parameter types. Java is strictly pass-by-value; for reference types, the copied value is the reference, not the object. Overload resolution prefers an exact match, then widening, then autoboxing, then varargs, in that order.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.