Introduction to Java Programming.
Chapter 1:
Introduction
1.10
Constants in Java: final Variables
In programming, a constant is a value
that, once assigned, cannot be changed during the program’s execution. Unlike
variables, which are designed to hold data that can vary, constants hold data
that remains fixed. In Java, the final keyword is used to declare constants.
1.10.1 What
are Constants?
●
Definition
|: Constants are named values
that are immutable, meaning their value cannot be altered once they have been
initialized. They provide a way to define fixed values that will be used
throughout a program.
●
Why They
Are Useful |:
○
Readability: Using named constants (e.g., PI instead of
3.14159) makes code much easier to understand. A developer reading the code
immediately knows the purpose of the value.
○
Maintainability: If a constant value needs to be updated
(e.g., a tax rate changes), you only need to change it in one place (where the
constant is defined), and the change will automatically propagate everywhere
the constant is used. Without constants, you would have to find and modify
every occurrence of that value, which is error-prone.
○
Preventing
Errors: By making a
value final, the compiler ensures that it cannot be accidentally changed later
in the program, preventing potential bugs.
○
Configuration
Settings: They are
commonly used for values that define global parameters or settings within an
application, such as MAX_USERS, DEFAULT_TIMEOUT, or DATABASE_NAME.
Example: The mathematical constant $\pi$ (pi) is a
perfect candidate for a constant because its value never changes.
1.10.2
Declaring final Variables
To declare a constant in Java, you use the
final keyword before the data type. By convention, constant names are written
in uppercase letters, with words separated by underscores (_). This
makes them easily distinguishable from regular variables.
●
Syntax:
final dataType
CONSTANT_NAME = value;
●
Examples:
// Declaring
constants using ‘final’
final int MAX_ATTEMPTS = 3;
final double PI
= 3.14159;
final String
DATABASE_URL = "jdbc:mysql://localhost:3306/mydb";
final boolean DEBUG_MODE = true;
// Example using
constants in a class
public class CircleCalculator {
// Instance constant
final double
PI_VALUE = 3.14159;
// Static constant (shared by all objects)
public static
final String APP_NAME = "My Awesome App";
// Method using constants
public void calculateArea(double radius) {
// Using the
instance constant
double area =
PI_VALUE * radius * radius;
System.out.println("Area: " + area);
// Using the
static constant
System.out.println("Application: " + APP_NAME);
}
public static void
main(String[] args) {
CircleCalculator
calculator = new CircleCalculator();
calculator.calculateArea(5.0);
// Static constant can also be accessed
using the class name
System.out.println("Running " + CircleCalculator.APP_NAME);
}
}
1.10.3 Rules for final Variables
The final keyword imposes strict rules on how a
variable can be used:
●
Must be
Initialized Once |:
A final variable must be initialized exactly once.
This can be done either:
⒈
At the time
of declaration.
⒉
In a
constructor (for instance final variables).
⒊
In a static
initializer block (for static final variables).
If a final variable is not initialized, the compiler
will generate an error.
// Example of final variables in Java
// 1. Final variable
initialized at declaration
final int a = 10; // Correct: initialized at declaration
// 2. Final
variable without initialization
// final int b;
// ❌ COMPILE-TIME ERROR: blank final field ‘b’ may
not have been initialized
// 3. Final
instance variable initialized in the constructor
class MyClass {
final int value; // Declared, not initialized here
// Constructor initializes the final
variable
public MyClass(int val)
{
this.value = val; // Correct: initialized in
constructor
// this.value = 20; // ❌ COMPILE-TIME ERROR: cannot assign a value to
final variable ‘value’
}
}
●
Cannot be
Reassigned |:
Once a final variable has been initialized, its value
cannot be changed or reassigned. Any attempt to modify its value after
initialization will result in a compile-time error.
public class FinalExample {
public static void
main(String[] args) {
// Final variables cannot be reassigned
once initialized
final int count = 5;
// count = 10; // ❌ COMPILE-TIME ERROR: cannot assign a value to
final variable ‘count’
final String
GREETING = "Hello";
// GREETING = "Hi"; // ❌ COMPILE-TIME ERROR: cannot assign a value to
final variable ‘GREETING’
// Printing the values
System.out.println("Count: " + count);
System.out.println("Greeting: " + GREETING);
}
}
●
Impact on
Objects (Reference is final,
Not the Object’s Content) |:
This is a crucial point to understand for final
variables that are objects (non-primitive types). When a reference variable is
declared final, it means that the variable can only point to one object. The reference
itself cannot be changed to point to a different object. However, the state
(the data within) of the object that the final reference points to can
still be changed, provided the object itself is
mutable.
public class FinalObjectExample {
public static void
main(String[] args) {
// Final reference to a StringBuilder object
final StringBuilder sb = new StringBuilder("Java");
System.out.println(sb); // Output: Java
// Modifying
the contents of the object is allowed
sb.append(" Programming");
System.out.println(sb); // Output: Java Programming
// Attempting
to reassign the final reference to a new object is NOT allowed
// sb = new StringBuilder("New
String");
// ❌ COMPILE-TIME ERROR: cannot assign a value to
final variable ‘sb‘
}
}
In this
example, sb is a final reference, so it will always
point to the same StringBuilder object that was
created initially. You cannot reassign sb to a
different StringBuilder object. However, because StringBuilder objects are mutable, you can still call
methods like append() on that same object to
modify its internal content. If you want an object whose content also cannot change, the class of that object must itself be designed to
be immutable (like String in Java).
1.10.4 When to Use final
Using final effectively contributes to better
code design and makes your programs more robust and easier to understand.
●
For True
Constants: Use final for
values that are genuinely constant throughout your application (e.g.,
mathematical constants, maximum limits, fixed error
codes). These are often declared as public static final to make them globally
accessible and to emphasize that they belong to the class rather than an
object.
●
Achieving
Immutability (of References): When you want to ensure that a reference variable (especially an
object reference) will always point to the same object after initialization.
This helps in preventing unexpected reassignments.
●
Method
Parameters: Declaring method
parameters as final indicates that the method will not modify the value of the
parameter. This can make code clearer, especially for primitive types.
●
Local
Variables: Using final for
local variables can sometimes improve readability by indicating that the
variable’s value won’t change after its initial assignment, making it easier to
reason about the code. It’s often used with anonymous inner classes or Lambda
expressions that access local variables.
●
Performance: While not its primary purpose, final
variables can sometimes allow the Java compiler and JVM to perform minor
optimizations, as they know the value won’t change. However, this performance
benefit is usually negligible and should not be the main reason for using
final. The main benefits are maintainability and readability.
By incorporating final variables into your
programming practice, you enforce data integrity, make your code more
predictable, and clearly communicate the intent of fixed values to other
developers (and your future self).