Lecture 8: Methods and scope

Objectives

  • Understand why methods exist and know how to write one yourself
  • Understand return statements
  • Understand method arguments
  • Know how to trace through methods calls in memory using the stack

Why are methods useful in computation?

  • Sharing complex libraries, such as SSL, deep learning, etc.
  • Allowing groups of people to work on the same codebase in parallel, to make large systems
  • Other examples?

What is a method?

We’ve seen methods, like main, already. You’ve also been writing method all semester for your homework assignments. Let’s take a formal look at what a method is and how it works:

public class MethodExamples {

    public static double func1(int a, int y){
        double result = a + y + 1.0;
        a = 7;
        y = 4;
        return result;
    }

    public static void func2(int a, int y){
        double result = a + y + 1.0;
        a = 7;
        y = 4;
        // no return statement required
    }

    public static void main(String args[]) {
        int x = 3;
        int y = 2;
        double result = func1(x, y);

        func2(x, y);    
    }
}  

Above, we have our main method, as well as two new methods, func1 and func2. All these methods take some number of arguments, but only func1 returns something using a return statement. Observe that func1 is declared as double func1 and has a return statement that returns a double. func2 is identical to func1 except that is has no return statement: therefore, its return type is void, like main. If you want a method to return a value, you must declare it to have a return type.

You can see that main above is calling func1 and func2 by passing the variables x and y into these methods. What happens inside these methods? Let’s trace it together now. You can check your work using the visualizer.

Note that nothing was printed; a return statement is different than a print statement.

Scoping rules

In the example above, we saw that each method as a local copy of the variable y, and it turned out these operate independently of each other; changes to y inside func1 did not affect the value of y in main. In formal terms, every block of code (between curly braces) has its own scope – it can only see the variables it defines locally, as well as any in the parent scope.

public class MethodExamples {
    public static void main(String args[]) {
        int x = 3;
        
        for(int i = 0; i < 4; i++){
            int k = 3;
            System.out.println(x + " " + i + " " + k);
        }
       
        System.out.println(x);
        System.out.println(i); // doesn't compile
        System.out.println(k); // doesn't compile
    }
}  

Watch what happens outside of our familiar for loop with i and k, which are both local scope only to the for loop in this example. You can see that i is created at the start of the loop and lasts through its entire execution, while k is re-created each time you are inside the loop: they are at different scopes. x is outside of the for loop, declared in the scope of the main method, so it is still available after the loop.

Scoping and methods

Now that we understand the idea of scope: that defining a variable between curly braces makes it visible only between those curly braces (including any nested curly braces), we can understand how scope is handled with method calls.

Each time a method is called, space for it is created on the stack, and its arguments are initialized with the values passed in. The variables inside the scope of the method cannot see any variables in other method scopes. This is why the y in func1 is different than the y in main, even though they have the same name.

Class Participation Activity 1 [15 min]

Let’s formally trace the first example above again, paying attention to scoping rules this time.

Follow along and create your own memory trace like we did in class (it must match ours); submit this on BB under the link “lecture 8 participation” by 1:00pm.

Variables declared outside of methods

It is possible to declare a variable at the class level, rather than the method level: these are called fields:

public class MethodExamples {
    int k = 11;

    public static double func1(int a, int y){
        double result = a + y + 1.0;
        a = 7;
        y = 4;
        k++;
        return result;
    }

    public static void func2(int a, int y){
        double result = a + y + 1.0;
        a = 1;
        y = 1;
        k++;
        // no return statement required
    }

    public static void main(String args[]) {
        int x = 5;
        int y = 6;
        double result = func1(x, y);

        func2(x, y);    
        k++;
    }
}  

Because the entire class is specified between those two outer-most curly braces, anything inside the class, including its methods, can see these fields, like k above.

Class Participation Activity 1 [15 min]

Let’s formally trace the field example above, paying attention to scoping rules this time.

Next class

We’ll trace through Quiz5 samples