Tino APCS

Parameters and Arguments

Parameters and arguments are used to pass information to a method. Parameters are used when defining a method, and arguments are used when calling the method.

Examine this sample code:

DrawingTool myPencil = new DrawingTool();
myPencil.turnLeft(60);
myPencil.forward(100);

In the above code, we use the DrawingTool’s turnLeft(double) method to turn the myPencil object by a given degrees counterclockwise. Since we wrote 60 inside the parentheses, the argument we are passing is 60.

If we don’t pass an argument, then we are calling the turnLeft() method, which is considered a different method by the Java compiler. That method turns the drawing tool 90 degrees counterclockwise. Since there are two methods named turnLeft, you would say that turnLeft is overloaded. The compiler knows which one we are trying to call by matching the types of the arguments to the parameter types in the method signature. We passed an int, so first it would look for a turnLeft(int), but that does not exist, so it would see that there is a turnLeft(double) and our int argument can be automatically converted to a double, so turnLeft(60) is compatible with the method turnLeft(double).

When defining a method, the list of parameters can contain multiple parameters. For example:

When this method is called, the arguments fed to the doMath method must be the correct type and must be in the same order. The first argument must be an int. The second argument can be a double or an int (since an int will automatically be converted by Java).

Arguments can be either literal values (2, 3.5) or variables (a, x).

Primitive vs Object parameters

When a method is called with an argument, the parameter receives the value of the argument. The value will always be a number, but the number can be interpreted differently depending on the type of the variable.

  • If the data type of the parameter is a primitive type, the value of the variable will be interpreted directly as a number, character or boolean value.
  • If the data type of the parameter is a class, then the parameter variable is a reference variable, which means its value is interpreted as the address of an object in memory. This means that anything the method does to that parameter will be done to the object at the address we passed in as our argument.

Here is an example:

import java.awt.Point;
    public class ParamDemo {
        public static void main(String[] args) {
            int x = 3;
            Point mp = new Point(x, 1);
            changeX(mp, x);
            System.out.println(mp.x);
        }
 
public static void changeX(Point p, int x) { x = x + 2; p.x = x; } }

Analysis:

First we will draw a diagram showing what happens in memory at runtime. In order to do this, first we need to discuss two sections of memory: the stack and the heap.

The stack is a place in memory where method calls are stored. Each method gets assigned its own section of the stack where all of the local variables used in that method are stored (including parameter variables).

The heap stores all the objects created during program execution, regardless of which method they were created in. Each object is stored at a memory address which we will label in our diagrams with an @ symbol followed by a number. For example, @67 means memory address 67.

Thus, the value of a variable whose type is a class will be a memory address like @67. For primitive values, since they store a value directly, we will simply write the numeric value stored.

When changeX is first called in the the main method, the stack and heap look like this:

Stack                                 Heap
main(@34) 
    args = @34                 String[] {} @34
    x = 3
    mp = @23                   Point (3, 1) @23

changeX(@23, 3)
    p = @23
    x = 3

Notice that the p variable in the changeX method, stores the same memory address (@23) as the mp variable from the main method. This means, mp and p both reference the same object. You might also notice that there is a local variable in the main method named x that has value 3 and a local variable named x in changeX that is also 3. Those are two different local variables that happen to have the same name. The value of the x in the main method (3) was passed in as an argument to the changeX method and the value of the x parameter in changeX was assigned that value (3).

After the first line of code in changeX x = x + 2, the value of the x variable in the changeX method is changed from 3 to 5, so the stack and heap would look like this:

Stack                                 Heap
main(@34) 
    args = @34                 String[] {} @34
    x = 3
    mp = @23                   Point (3, 1) @23

changeX(@23, 3)
    p = @23
    x = 5

Notice that the x variable in the main method is unaffected by changing the value of the x variable in changeX. They are two different variables, so changing one has no affect on the other.

Next, the line p.x = x is executed. This means, go to the object referenced by p (the Point object at memory address @23), and change the value of its x attribute to the value of the local x variable (5). The stack and heap would now look like this:

Stack                                 Heap
main(@34) 
    args = @34                 String[] {} @34
    x = 3
    mp = @23                   Point (5, 1) @23

changeX(@23, 3)
    p = @23
    x = 5

Notice, since the Point object at address @23 was changed, that change will still be in effect when accessed through the mp variable in the main method.

The changeX method is now finished, so it is removed from the stack and the stack and heap would look like this:

Stack                                 Heap
main(@34) 
    args = @34                 String[] {} @34
    x = 3
    mp = @23                   Point (5, 1) @23

In the main method, the next line of code executes System.out.println(mp.x) which prints the value of the x attribute of the Point object referenced by mp (at memory address @23), which would print 5.

Dark Mode

Outline