Skip to content
Study Hall
Lesson 2 of 3Methods
Unit 5 · Lesson 2 of 3

Parameters, Arguments and Scope

How values get into a method, why changing a parameter never changes the caller's variable, where a variable is allowed to exist, and how one name can belong to several methods.

6 min read11 practice questionsAsk AI about this →

Key things to remember

  1. 1A parameter is in the definition and has a type; an argument is at the call and is a value.
  2. 2Java matches arguments to parameters by position — number, order and type must all agree.
  3. 3Java is pass by value: a primitive argument is copied, so reassigning the parameter never changes the caller's variable.
  4. 4To make a change stick, return the new value and assign it: score = addTen(score);
  5. 5A variable exists from its declaration to the closing brace of its block, and nowhere else.
  6. 6Overloading means same name, different parameter list. A different return type alone is not enough.

A method that always does the same thing to the same values is not much use. Parameters are what make a method general: they are the blanks in the definition, filled in fresh at every call. Getting the vocabulary straight makes the rest of this topic much easier — a parameter lives in the definition, an argument lives at the call, and Java's job is to match them up.

TermWhere it appearsExample
ParameterIn the method definition, with a typepublic static int square(int n) — n is the parameter
ArgumentAt the call, as a valuesquare(7) — 7 is the argument
MatchingDone by Java, at compile timeNumber, order and type must all line up
public static void showRecord(int wins, int losses) {
    System.out.println(wins + " wins and " + losses + " losses");
}

// in main:
showRecord(3, 7);        // 3 wins and 7 losses
showRecord(7, 3);        // 7 wins and 3 losses  -- compiles fine, means something else

// showRecord(3);        // will not compile: wrong number of arguments
// showRecord(3, "7");   // will not compile: String cannot become int
Java matches arguments to parameters by position alone. Wrong count or wrong type is caught by the compiler; wrong order is not, because it cannot read your variable names or your mind.
An argument is copied into the parameter. The method never touches the original.public static void main(String[] a) { int n = 5; bump(n); System.out.println(n); // 5}public static void bump(int x) { x = x + 100; // the copy only}What is in memoryn (in main)5copyx (in bump)5after x = x + 100n (in main)5x (in bump)105when bump ends, its x is destroyedand n never knew anything happenedJava always passes a copy of the value, so reassigning a parameter cannot change the caller's variable.A method that must hand something back has to return it: n = bump(n);For an object or an array the copied value is the reference, so the contents can still be changed — the variable itself cannot.
Fig 1The argument's value is copied into the parameter; the original variable is untouched.

Pass by value

This is the single most misunderstood rule in the unit. When you pass a primitive such as an int or a double, Java copies the value into the parameter. The parameter is a brand new variable that happens to start with the same contents, created when the method starts and destroyed when it ends. Changing it changes the copy and nothing else, so the caller's variable is completely safe — and completely unaffected, which is the part that surprises people. Even if the parameter had the same name as the caller's variable, it would still be a separate box in memory.

public class PassByValue {

    public static void addTen(int number) {
        number = number + 10;
        System.out.println("Inside the method: " + number);
    }

    public static void main(String[] args) {
        int score = 5;
        addTen(score);
        System.out.println("Back in main: " + score);
    }
}

// Output:
// Inside the method: 15
// Back in main: 5
score is still 5. The method changed its own copy, called number, and that copy vanished when the method ended.
public static int addTen(int number) {
    return number + 10;
}

// in main:
int score = 5;
score = addTen(score);                 // the assignment is what changes score
System.out.println(score);             // 15
To make a change stick, hand the new value back and store it. Leave off the assignment and score stays 5 — the new value is computed and thrown away.

Scope and shadowing

Scope is the region of code where a name is recognized. In Java the rule is mechanical: a variable exists from the line that declares it to the closing brace of the block that contains it, and nowhere else. Outside that block the name simply does not exist, so using it is a compile error rather than a run-time surprise. This is a feature — it means a counter called i in one method can never collide with a counter called i in another. It also means a variable declared inside a loop body is created and destroyed on every pass, which is right for a scratch value and wrong for an accumulator.

A variable lives from its declaration to the closing brace of its own block.public static void main(String[] args) {int a = 1;visible here: aif (a == 1) {int b = 2;visible here: a and bfor (int i = 0; i < 3; i++) {int c = i * 2;visible here: a, b, i, c} i and c die here} b dies here} a dies here — the method is overc is created fresh on every pass of the loop, so it cannot remember anything from the pass before."Cannot find symbol" almost always means you used a name outside the block that declared it.
Fig 2Nested blocks: an inner block can see out, but an outer block can never see in.
public static void main(String[] args) {
    int total = 0;                      // scope: the whole of main

    for (int i = 1; i <= 3; i++) {      // scope of i: the for loop only
        int doubled = i * 2;            // scope of doubled: this pass of the body
        total = total + doubled;        // total is visible here -- inner sees out
    }

    System.out.println(total);          // 12  (2 + 4 + 6)
    // System.out.println(i);           // error: cannot find symbol
    // System.out.println(doubled);     // error: cannot find symbol
}
total = 12. Both i and doubled ceased to exist at the loop's closing brace.
public class Shadow {
    static int count = 10;              // class variable

    public static void show() {
        int count = 99;                 // local variable shadows the class one
        System.out.println(count);        // 99  -- the nearest declaration wins
        System.out.println(Shadow.count); // 10  -- named explicitly
    }

    public static void main(String[] args) {
        show();
        System.out.println(count);      // 10  -- the class variable never changed
    }
}
Output: 99, then 10, then 10. Two different variables sharing one name is legal, compiles, runs, and confuses everybody — so choose distinct names instead.

Overloading

Java lets several methods share a name as long as their parameter lists differ — in the number of parameters, their types, or their order. This is called overloading, and Java picks the right one by looking at the arguments at the call. It is why System.out.println works with an int, a double, a String or a boolean: those are separate overloaded methods, not one clever one.

public static int add(int a, int b) {
    return a + b;
}

public static double add(double a, double b) {      // different types
    return a + b;
}

public static int add(int a, int b, int c) {        // different count
    return a + b + c;
}

// in main:
System.out.println(add(2, 3));          // 5    -- picks the int version
System.out.println(add(2.5, 3.5));      // 6.0  -- picks the double version
System.out.println(add(1, 2, 3));       // 6    -- picks the three-parameter version
One name, three methods. A different return type alone is not enough to overload: the call site never mentions a return type, so Java would have nothing to choose with.

Worked examples

Reveal one step at a time and try to beat it to the next line.

Example 1
What does this print? public static void grow(int n) { n = n * 2; System.out.println(n); } called as int size = 6; grow(size); System.out.println(size);
Example 2
Explain the compile error in for (int i = 0; i < 5; i++) { int sum = 0; sum += i; } System.out.println(sum);
Example 3
Which overload runs for each call, given add(int, int), add(double, double) and add(int, int, int)? Calls: add(4, 5), add(4.0, 5.0), add(1, 2, 3), add(4, 5.0)
Example 4
A method is meant to swap two ints: public static void swap(int a, int b) { int t = a; a = b; b = t; }. Why does it never work?

Where marks get lost

  • Passing arguments in the wrong order when they are the same type — the program compiles perfectly and quietly computes the wrong answer.
  • Expecting a method to change the caller's variable by reassigning a parameter; with primitives, it never can.
  • Calling addTen(score); and forgetting the score = part, so the returned value is computed and discarded.
  • Using a loop counter after the loop has ended, when the header's declaration limited it to the loop.
  • Giving a local variable the same name as a class variable and then wondering why the class variable never changes.

Flashcards 10

Parameter or argument: int n in void show(int n)?
Parameter or argument: the 7 in show(7)?
How does Java match arguments to parameters?
What does pass by value mean?
+ 6 more

Practice

1
int score = 5; addTen(score); where addTen is void addTen(int number) { number += 10; }. What is score afterwards?
2
In square(7), is the 7 a parameter or an argument?
3
With public static int addTen(int n) { return n + 10; }, what is score after int score = 5; score = addTen(score);?
4
Which pair of methods is a valid overload?
5
for (int i = 0; i < 5; i++) { ... } System.out.println(i); gives cannot find symbol. Why?
6
What does this print? static int count = 10; with static void show() { int count = 99; System.out.println(count); }
7
What is printed? int total = 0; for (int i = 1; i <= 3; i++) { int d = i * 2; total += d; } System.out.println(total);
8
Order these scopes from the widest reach to the narrowest.
  1. 1A local variable declared at the top of a method
  2. 2A variable declared inside an if block within that loop body
  3. 3A variable declared inside that method's for loop body
  4. 4A class variable declared inside the class but outside every method
9
Match each term to its meaning.
Parameter
Argument
Pass by value
Scope
Overloading
10
A method void swap(int a, int b) swaps its two parameters, but the caller's variables never change. What is the cleanest fix?
11
Give the term for two methods with the same name but different parameter lists.

Spot a mistake on this page? Let us know