Scope is a fundamental concept in programming. It refers to the accessibility of named entities in our code.

In this topic, we will look at:

  • The different types of named entities in our code.
  • The scope of these named entities.
  • The nesting of scope within our code.
  • The rules for accessing named entities.




Named entities

Our programs will always be full of named entities, such as:

  • method names (e.g. main(), getAge()),
  • variable (and field) names (e.g. bob, age),
  • type names (e.g. Person, String, int), etc.

For this topic on scope, we are just going to look at the first two (methods and variables+fields).




Scope of named entities

When we talk about the scope (of a method or variable), we are talking about its “accessibility”.

In other words, from which part(s) of our code can we access that named entity?

  • Something “in scope” may be accessed.
  • Something “not in scope” cannot be accessed.

Consider the following bit of code:

public class Course {
   private String name;
   private int cap;
   private ArrayList<String> students;
   private static int nextID = 0;
   
   public Course(String name, int max) {
      int foo = 23;
      ...   
   }
   
   public boolean enroll(String studentID) {
      int bar = 45;
      ...
   }
   
   public static int getNumberOfCourses(boolean onlyActive) {
      String bar = null;
      ...
   }
}


1. If we are inside the Course() constructor, what’s in scope?

Edit

  • All fields:
    • name (instance field)
    • cap (instance field)
    • students (instance field)
    • nextID (static field)
  • All local variables:
    • name (parameter)
    • max (parameter)
    • foo (locally-declared variable)
  • All methods:
    • enroll() (instance method)
    • getNumberOfCourses() (static method)


2. If we are inside the enroll() instance method, what’s in scope?

Edit

  • All fields:
    • name (instance field)
    • cap (instance field)
    • students (instance field)
    • nextID (static field)
  • All local variables:
    • studentID (parameter)
    • bar (the locally-declared variable inside enroll())
  • All methods:
    • enroll() (instance method – i.e. itself for recursion)
    • getNumberOfCourses() (static method)


3. If we are inside the getNumberOfCourses() static method, what’s in scope?

Edit

  • Only static fields:
    • nextID (static field)
  • All local variables:
    • onlyActive (parameter)
    • bar (the locally-declared variable inside getNumberOfCourses())
  • Only static methods:
    • getNumberOfCourses() (static method – i.e. itself for recursion)




Nesting scope

Above we talked about scope across methods/constructors.

But we can also talk about scope within a method/constructor, which is defined by the nested { ... } blocks:


public class Course {
   private String name;
   private int cap;
   private ArrayList<String> students;
   ...
   
   public boolean enroll(String studentID) {
      int bar = 45;
      String name = "Local variable for fun";
      
      // Check there's space
      if (students.size() < cap) {
         
         // Print current students     
         for (String id: students) {
            System.out.println(id);
         }
         
         // Check not already enrolled
         for (String id: students) {
            if (studentID.equals(id)) {
               boolean result = false;
               return result;
            }
         }
         
         // Not already enrolled in the course, so enroll them
         students.add(studentID);
         
         boolean result = true;
         return result;
      } else {
      
         // No space in course
         boolean result = false;
         return result;
      }
   }
   
   ...
}


We can visualise the nesting of our scopes (for the enroll() method) as follows:

Edit

To keep the diagram tidy, not all possible arrows are drawn. But in a nutshell, the general rules are:

Edit All fields may be accessed from anywhere in any of the method/constructor scopes.

Edit All fields may be accessed from anywhere in any of the nested block scopes.

Edit Parameters may be accessed from anywhere in respective method/constructor scope (including nested block scopes).

Edit Local variables may be accessed after they have been declared.

Edit Local variables cannot be accessed before they have been declared.

Edit Local variables cannot be accessed from an outer scope.

Edit Local variables cannot be accessed between block scopes that are not nested.

Edit Local variables and parameters cannot be accessed from another method.

Of course, the usual rules concerning static fields/methods also need to be observed.