Global variables and methods (static)
Lesson content
- What is a global (static) variable?
- Calling and using a global (static) variable
- What is a global (static) method?
- Calling and using a global (static) method
- Most common errors
What is a global (static) variable?
Objects have attributes and methods that can be accessed and used only once the object is initialized. Also, each object has its own separate attribute values.
In some situations, however, it is useful for multiple objects (from the same or different classes) to share a single variable. Such variables are visible throughout the entire program and are called global variables.
In Java, global variables are marked with the reserved word static and are written within the class body as class attributes, so they are also often called static variables or static attributes:
1 static dataType variableName;
Calling and using a global (static) variable
Because a global variable is not tied to any specific object, using this variable does not require initializing an object of the class to which it belongs. Instead, it is accessed directly via the class name within which it is defined:
1 ClassName.variableName
Although static variable calls can also be made through initialized objects of that class, this is not considered to be good practice. It unnecessarily initializes the object and takes up memory space.
Example 1
Create a class Hotel and define a global variable remainingFreeRooms within it. Set its initial value to 100.
1 class Hotel {
2 static int remainingFreeRooms = 100;
3 }
Create a class TestHotel that sets the value of this global variable to 5.
1 class TestHotel {
2
3 public static void main(String[] args) {
4 // No initialization of a Hotel
5 // object is required to use the
6 // global variable. The call is
7 // made through the class name.
8 Hotel.remainingFreeRooms = 5;
9
10 System.out.println("There are: " + Hotel.remainingFreeRooms +
11 " free rooms remaining");
12 }
13 }
It is important to note again that, unlike regular attributes where each object has its own attribute values, for global variables (static variables), all objects of the class share the same static variable.
Example 2
Use the Hotel class from the previous example.
Create a class TestHotel2 that creates two objects
of the Hotel class, changes the value of this global
variable, and prints its value via these objects.
1 class TestHotel2 {
2
3 public static void main(String[] args) {
4 // Let's say we decide to make two Hotel objects
5 Hotel h1 = new Hotel();
6 Hotel h2 = new Hotel();
7
8 // If we change the value of a global variable,
9 // the change affects all objects of that class
10 // because they share that global variable.
11 Hotel.remainingFreeRooms = 5;
12
13 //It will print "There are: 5 free rooms remaining"
14 // in both cases because all Hotel objects share the
15 // same global variable.
16 System.out.println("There are: " + h1.remainingFreeRooms +
17 " free rooms remaining");
18 System.out.println("There are: " + h2.remainingFreeRooms +
19 " free rooms remaining");
20 }
21 }
What is a global (static) method?
Sometimes, there is a need for methods that provide some general functionality that is not strictly tied to a specific class. Such methods are often good candidates to become global methods.
In Java, global methods are also marked with the reserved word static and are often called static methods. These methods are defined within the class body the same way as any other method:
1 static returnType methodName(...parameters...) {
2 // Method body
3 }
Calling and using a global (static) method
The difference compared to a regular method is that you do not need to initialize an object of that class to use the method. Instead, the call is made via the class name:
1 ClassName.methodName(arguments);
Although static variable calls can also be made through initialized objects of that class, this is not considered to be good practice. It unnecessarily initializes the object and takes up memory space.
Because of this, static attributes and methods cannot be called using the reserved word this — unless the object has been initialized. The call should be made by referencing the class name.
In fact, if you take a closer look, you can see that the main method is a static method. This is necessary because it is called at the beginning of the program execution, before any objects are created.
Example 3
Create a Calculator class and define two global methods within it: add and subtract. Both methods take two integers as parameters and return the result of the addition or subtraction.
1 class Calculator {
2 static int add(int a, int b){
3 return a+b;
4 }
5
6 static int subtract(int a, int b){
7 return a-b;
8 }
9 }
Create a TestCalculator class that, within its main method, calls the add and subtract methods to add and subtract numbers 5 and 10.
1 class TestCalculator {
2
3 public static void main(String[] args) {
4 int a = 5;
5 int b = 10;
6
7 int result1 = Calculator.add(a, b);
8 int result2 = Calculator.subtract(a, b);
9
10 System.out.println(result1);
11 System.out.println(result2);
12 }
13 }
Every class in Java can have both regular attributes and static attributes, as well as regular methods and static methods. There are no restrictions in this regard, so a class can have all of them at once. Just keep in mind that:
- From regular methods, you can directly call everything: both regular and static attributes, and both regular and static methods.
- From static methods, you can directly call ONLY static attributes and methods (unless you create an object of the class within a static method or pass it as a parameter to access regular attributes and methods).
Example 4
Create a Circle class which has:
A static (global) variable pi with the value of 3.141592.
An attribute diameter which is a real number.
A static (global) method calculateCircumference that receives the circle’s diameter as a parameter, multiplies it by pi, and calculates and returns the circumference of the circle.
A method printCircle that prints the diameter and circumference of the circle on the screen and calls the calculateCircumference method to obtain the latter.
1 class Circle {
2
3 //Static variable
4 static double pi = 3.141592;
5
6 //"Regular", non-static attribute
7 double diameter;
8
9 //Static method
10 static double calculateCircumference(double diameter) {
11 //The diameter is entered as a parameter because the
12 // non-static attribute diameter cannot be called from
13 //this method because it is a static method.
14 return diameter * pi;
15 }
16
17 //"Regular", non-static method
18 void printCircle() {
19 //Here, the static method calculateCircumference is called
20 //from a non-static method printCircle, but the attribute diameter
21 //must be passed to it as a parameter - the static method
22 //calculateCircumference cannot access it directly.
23 System.out.println("Circle diameter is " + diameter
24 + " and its circumference is " +
25 calculateCircumference(diameter));
26 }
27
28 }
Create a TestCircle class and within its main method:
- First, directly call the static calculateCircumference method to calculate the circumference of a circle with a diameter of 300 and then print the result on the screen.
- Second, create an object of the Circle class with a diameter of 20. Calculate and print the circumference of the created circle, as well as the diameter by calling the printCircle method.
1 class TestCircle {
2
3 public static void main(String[] args) {
4 //Calling a static method without initializing an object
5 double circumference = Circle.calculateCircumference(300);
6
7 System.out.println(circumference);
8
9 //We make an object and use its ordinary attributes and methods
10 Circle k = new Circle();
11
12 k.diameter = 2.5;
13
14 k.printCircle();
15 }
16 }
A bit of discussion is needed about the provided solution. The calculateCircumference method of the Circle class is static, so if we only want to calculate the circumference of a circle, we can call it directly and do not need to create an object of the Circle class. For this, we must pass the circle’s diameter as a parameter, because this method cannot access the diameter attribute of the Circle class (since it is not a static attribute). It can access the pi attribute (since it is static), which is also needed for the calculation, so we do not pass it as a parameter.
The Circle class is somewhat mixed because, in addition to static attributes, it also has regular attributes and methods. If we create an object of the Circle class and enter a value for the diameter attribute (in this case, it is 2.5), we have the option to store the diameter of the circle within this objects attribute and use the printCircle method to calculate both the circumference and print the diameter and circumference. The printCircle method actually calls the static calculateCircumference method and passes the value of the diameter attribute to it (because the calculateCircumference method cannot access it directly), then prints the returned value (the circumference) and the diameter on the screen.
In the case where we are only calling the static method (the first scenario), the diameter of the circle is not saved anywhere, so it “disappears” after the calculateCircumference method has terminated (finished execution). In the second scenario, we created an object of the Circle class that stores the diameter of the circle, and this object (as well as the diameter) can be used later.
When is a method a good candidate to be a static method? Possible cases include:
- The method follows the input-output principle: it receives all the necessary data through parameters and returns the result as a return value or prints it on the screen.
- The method does not use attributes in its operation.
- The method has general functionality or forms a separate, encapsulated unit, such as various calculators, converters, etc.
- The method is generally called once, so the object is no longer needed once the method has finished execution.
Most common errors
Some of the most common syntax errors related to writing and using static attributes and methods are:
Forgetting to write the word static before an attribute or method, then trying to call them as if they are static (i.e., using the class name).
Calling regular methods or attributes using the class name as if they are static.
Writing the word static after the attribute type instead of before it, e.g.:
1 int static number;
Instead of (correct):
1 static int number;
- Writing the word static after the return type of method instead of before it, e.g.:
1 int static add(int a, int b) {
2 return a + b;
3 }
Instead of (correct):
1 static int add(int a, int b) {
2 return a + b;
3 }
- Calling non-static attributes and methods from a static method within the same class.
- Calling static attributes and methods using the word this — if the object has not been created.
Other common mistakes that are not syntax errors but affect the program’s functionality are:
- Creating an object and then calling a static attribute or method through that object. Although this is not a syntax error, it unnecessarily initializes the object and takes up memory space. For example, if the add method is static, this kind of call is not the best solution:
1 Calculator c = new Calculator();
2 int sum = c.add(34, 88);
Instead, it is much better like this:
1 int sum = Calculator.add(34, 88);