Method ScopeS2C Home « Method Scope
You may be familiar with terminology such as global variables and local variables from languages such as JavaScript but this isn't the most accurate way to describe variables and their scope in Java. In fact Java comes with three kinds of scope and we name variables according to the scope they reside in as detailed in the table below. In this lesson we will focus on local variables that are contained within a method.
Variable | Scope | Lifetime |
---|---|---|
static | Static variables apply to the class as a whole and are declared within the class but outside a method. | Exists for as long as the class it belongs to is loaded in the JVM. See the Static Members lesson for more information. |
instance | Instance variables apply to an instance of the class and are declared within the class but outside a method. | Exists for as long as the instance of the class it belongs to. See the Instance Variables & Scope lesson for more information. |
local | Local variables apply to the method they appear in. | Exists until the method it is declared in finishes executing. |
Defining A ScopeTop
In Java we can declare variables anywhere within a block of code. A block starts with its opening curly brace and ends with its closing curly brace. A block and where it resides defines the type of the variable and the scope of the enclosed data. Therefore each time you start a new block of code you start a new scope. As a general rule of thumb, variables declared within a scope are not visible and therefore accessible outside that scope. Scope determines the visibility and lifetime of the variables within it. The following diagram should help with understanding of scope concept.
Method Scope Boundaries
A method scope begins with its opening curly brace and ends with its closing curly brace. If the method is passed parameters (more on this a bit later) these are also included in the scope. A scope can be nested within another scope and the variables from the outer scope are available to the inner scope. The reverse is not true and the outer scope knows nothing of the variables within the inner scope. In this way we are localizing the variable within this scope and protecting it from access and modification from the outside world. This forms the basis of encapsulation which we look at again in the OO Concepts section of the site in the Encapsulation and Nested Classes lessons.
Local Variable Rules
- Local variables used within a method are not automatically initialized to a default value and as such should be initialized on creation, before use or dynamically initialized at runtime from other variables.
- Each time a scope is entered the local variables that are declared with an initializer are reset to the initializer value.
- Variables declared in an inner scope cannot have the same name as variables declared in an outer scope.
Understanding Method ScopeTop
To get to grips with how method scope and the rules associated with it work let's write a simple program to illustrate some of the points made above. With your text editor open, cut and paste the following code into it. Don't
worry about the while loop
for now as we will go into greater detail about this construct in the Loop Statements lesson. For now it's enough to know that
the while loop
iterates over code until a condition is met.
package com.server2client;
/*
Initialising and using char primitives
*/
public class Counter {
public static void main (String[] args) {
byte a;
byte b = 0;
while (a < 5) {
// Dynamically initialized at runtime
byte c = a;
System.out.println("c = " + c);
byte b = 0;
b++;
System.out.println("b = " + b);
a++;
}
System.out.println("c = " + c);
}
}
Running the Counter
class produces the following output:
Ok the compile has failed with 2 errors as shown in the screenshot above. The reason for this is that we already declared the b
variable right at the start of the main()
method. This breaks the
following rule: Variables declared in an inner scope cannot have the same name as variables declared in an outer scope. So to correct this change all references and the string within the while loop
for the b
variable to d
. The second error occurs because we are trying to access the inner scope variable c
from the outer scope (the last line of code in the method). In fact by the time we hit this code all variables within the inner scope no longer exist as they only last as long as the lifetime of the scope they reside in. Change the reference and the string from variable c
to a
.
Running the Counter
class produces the following output:
Ok the above errors have been fixed but we now have a further error. We are trying access the a
variable in the while loop
before initializing it thus breaking the following rule: Local variables used within a method are not automatically initialized to a default value and as such should be initialized on creation, before use or dynamically initialized at runtime from other variables. So initialize the a
variable with a value of 0
.
Running the Counter
class produces the following output:
Ok we now have some output. Can you see that variable d
is always 1? This is because it gets reinitialized each time the loop is entered as per the following rule: Each time a scope is entered the local variables that are declared with an initializer are reset to the initializer value.
Parameters & Method Scope Top
In the earlier discussion on method scope we mentioned that a method's parameters, when present are included in scope. When you think about it every time we use the main()
method we are including the String[] args
parameter in its scope. Lets see how to use this parameter within a method with a code example. With your text editor open, cut and paste the following code into it:
package com.server2client;
/*
Using a method parameter
*/
public class UsingAParameter {
public static void main (String[] args) {
System.out.println("Have a nice day, " + args[0]);
}
}
Running the UsingAParameter
class produces the following output:
The run failed with an ArrayIndexOutOfBoundsException
exception as our args
array is empty. We can fix this by changing the run configuration for our IDE. In IntelliJ click on the run configurations button as shown in the screenshot and select Edit Configurations..., the process is similar in other IDEs:
Add your name in the Program arguments pane and press OK
Rerun the UsingAParameter
class which will produce the following output but with your name:
Final Local Variables Top
We can also make the value of a local variable constant so it can't be changed within a method. In fact trying to do so will cause a compiler error. The following code illustrates this:
package com.server2client;
/*
A Class
*/
public class A {
public static void main(String[] args) {
usingFinalLocal ();
}
public static final void usingFinalLocal() {
final int i = 0;
i = 0;
}
}
The above screenshot shows the result of trying to compile class A
.
You can also use the final
keyword to create final instance variables, within parameter lists,
when creating java constants and for preventing inheritance/overriding.
The StackTop
So, as we know, a local variable applies to the method it appears in and exists until the method it is declared in finishes executing. What we haven't mentioned so far is that the method we are executing gets placed on the Stack. If another method is called from within this method, then that gets placed on the top of the Stack and so on. The following slide show shows this in action, just press the button to step through it.
So to summarize, a local variable is alive as long as its method exists on the Stack. You can only use a methods local variables while the method is at the top of the stack (is executing).
Related Quiz
Fundamentals Quiz 5 - Method Scope Quiz
Lesson 6 Complete
In this lesson we looked at method scope and what scope and its definition mean.
What's Next?
In the next lesson we look at the arithmetic operators available for use in Java.