Constants (final)

Lesson content

  • What is a constant (reserved word final)
  • Declaring and calling constants, naming conventions for constants
  • Static constants
  • Most common errors

What is a constant (reserved word final)

Sometimes, there is a need to store some value (in the program) which never changes. Examples include mathematical constant values (like pi which always has the value 3.141592) but also other values which never change (birthdate of a person, eye color, number of apartments in a building). These values ae called constant values (or constants for short), and the Java language supports their declaration and usage in a similar way as variables are declared and used.

Constants are similar to variables in that they hold a value. The difference is that a variable can be reassigned a new value at any time and an unlimited number of times, while constants must receive an initial value that cannot be changed later. Hence, the name “constant.”

Declaring and calling constants, naming conventions for constants

If you need to define a constant within a Java class, the reserved word final is used. Constants are defined as attributes, with the word final placed before the attribute type:

1 final value_type CONSTANT_NAME = value;

By convention, constant names are written in all uppercase letters (“PI”, “INTEREST_RATE”). If the constant name consists of multiple words, the words are separated by underscores (“MIN_INTEREST_RATE”).

A constant must be assigned a value immediately upon declaration or possibly in the constructor, as it cannot be changed later. If an attempt is made to assign a new value to a constant later, the Java compiler will interpret it as a syntax error.

Calling a constant is done in the same way as calling a class attribute. The only difference is that constants can never be assigned a new value.

Example 1

Create a Hotel class wih has:

  • an attribute name
  • a constant TOTAL_NUMBER_OF_ROOMS with the value 130
1     class Hotel {
2 
3         String name;
4 
5         final int TOTAL_NUMBER_OF_ROOMS = 130;
6     }

Create a TestHotel class that, within it’s main method, creates a new Hotel object, sets the hotel name to “Hilton,” and prints the hotel’s name and the total number of rooms on the screen.

 1 class TestHotel {
 2 
 3     public static void main(String[] args) {
 4         Hotel h = new Hotel();
 5 
 6         h.name = "Hilton";
 7 
 8         // The following command is not permitted,
 9         // constants cannot have their initial value changed
10         //h.TOTAL_NUMBER_OF_ROOMS = 32;
11 
12         System.out.println("Hotel: " + h.name + 
13             ", total number of rooms: " +
14                 h.TOTAL_NUMBER_OF_ROOMS);
15     }
16 }

From the example, you can see that the constant TOTAL_NUMBER_OF_ROOMS receives the value 130 immediately upon declaration, while name is a regular attribute.

Later, in the main method of the TestHotel class, both the attribute and the constant can be accessed, but the constant’s value cannot be reassigned.

Practically speaking, this example isn’t ideal because it implies that all hotels must have exactly 130 rooms. In the next example, the constant will be assigned a value in the constructor, allowing each hotel to have a different total number of rooms (which cannot be changed later).

Example 2

Create a Hotel2 class which has:

  • an attribute name
  • a constant TOTAL_NUMBER_OF_ROOMS
  • a constructor that takes the hotel name and total number of rooms as parameters and sets these values for the name attribute and the constant TOTAL_NUMBER_OF_ROOMS
 1     class Hotel2 {
 2 
 3         String name;
 4 
 5         final int TOTAL_NUMBER_OF_ROOMS;
 6 
 7         Hotel2 (String name, int TOTAL_NUMBER_OF_ROOMS){
 8             this.name = name;
 9             this.TOTAL_NUMBER_OF_ROOMS = TOTAL_NUMBER_OF_ROOMS;
10         }
11     }

Create a TestHotel2 class that, within it’s main method, creates two Hotel2 objects and:

  • sets the first hotel’s name to “Continental” and a total of 300 rooms
  • sets the second hotel’s name to “Hilton” and a total of 250 rooms
  • prints all data for both hotels on the screen.
 1     class TestHotel2 {
 2 
 3         public static void main(String[] args) {
 4             Hotel2 h = new Hotel2("Continental", 300);
 5 
 6             Hotel2 h2 = new Hotel2("Hilton", 250);
 7 
 8             // Next commands are not allowed, constants
 9             // cannot have the initial value changed
10             //h.TOTAL_NUMBER_OF_ROOMS = 32;
11             //h2.TOTAL_NUMBER_OF_ROOMS = 155;
12 
13             System.out.println("Hotel: " + h.name + 
14             ", total number of rooms: " +
15                     h.TOTAL_NUMBER_OF_ROOMS);
16 
17             System.out.println("Hotel: " + h2.name + 
18                 ", total number of rooms: " +
19                     h2.TOTAL_NUMBER_OF_ROOMS);
20         }
21     }

From the example, you can see that the constant TOTAL_NUMBER_OF_ROOMS is assigned a value within the constructor. This means that each object of the Hotel2 class can have a different total number of rooms, and the value can be passed when the object is created (through the constructor).

As in the previous example, in the main method of the TestHotel2 class, both the attribute and the constant can be accessed, but the constant’s value cannot be reassigned.

Static constants

For some constants, it’s desirable for them to be globally visible, so, in addition to the word “final,” they are also marked with the reserved word “static”. Calling these global constants (static constants) is the same as making calls to global variables — it is done through the class name.

1 static final value_type CONSTANT_NAME = value;

Unlike regular constants, static constants cannot be initialized in the constructor, but only upon declaration (or possibly in so-called static blocks of code).

Example 3

Create a Mathematics class which has:

  • a static constant PI with a value of 3.141592
  • a static constant E with a value of 2.71
1     class Mathematics {
2 
3         static final double PI = 3.141592;
4 
5         static final double E = 2.71;
6     }

Create a TestMathematics class that, in the main method, calculates the circumference of a circle with a diameter of 2 (using the formula diameter * PI) and prints it on the screen. Additionally, the method prints the value of the constant E on the screen.

 1 class TestMathematics {
 2 
 3     public static void main(String[] args) {
 4 
 5         // Static constants are called by
 6         // using the class name - same as
 7         // global variables
 8         double circumference = 2 * Mathematics.PI;
 9 
10         System.out.println("Circle circumference is: " + circumference);
11 
12         System.out.println("Constant E is: " + Mathematics.E);
13     }
14 }

For clarity, let’s now summarize the differences between “regular” (non-static) attributes, global variables (static attributes), constants, and global constants (static constants):

  • “Regular” (non-static) attribute (i.e. String firstName;)
    • can change values
    • each object has its own value for this attribute
    • access through an initialized object.
  • Global variable (static attribute) (i.e. static String franchiseName;)
    • can change values
    • all objects of that class share one value for this attribute (global value at the class level)
    • access through class name (no object is created)
  • Constant (final) (i.e. final int BIRTH_YEAR;)
    • cannot change values (constant value)
    • each object has its own value for this constant
    • value is assigned either during declaration or through the constructor
    • access through an initalized object
  • Global constant (static final constant) (i.e. static final int NUMBER_OF_PARENTS;)
    • cannot change values (constant value)
    • all objects of that class share one value for this attribute (global constant value at the class level)
    • value is assigned either during declaration or in a static block of code
    • access through class name (no object is created).

The reserved word “final” can also be used with class and method definitions, but in these cases, it has a completely different meaning. This type of usage is closely tied to inheritance and will be explained in detail in the chapter on inheritance.

Most common errors

Some of the most common syntax errors related to writing and using constants and static constants are:

  • Forgetting to assign an initial value to a constant (whether static or not) during declaration.

  • Trying to assign a different value to a constant (whether static or not) after the initial value has been assigned (during declaration).

  • Writing the words static and/or final after the type of the constant instead of before it, e.g.:

1     int final static NUMBER = 4;

Instead of (correct):

1     static final int NUMBER = 4;

or (also correct):

1     final static int NUMBER = 4;

Other common errors that are not syntax errors, but affect the program’s behavior:

  • Creating an object and then calling a static constant through that object. Although this is not a syntax error, it unnecessarily initializes an object and consumes memory space.