Welcome to this lesson on static members in Java! As you delve deeper into object-oriented programming, understanding static is crucial. The static keyword is a non-access modifier in Java that applies to members of a class: fields (variables), methods, blocks, and even nested classes. It fundamentally changes how these members behave and how they are associated with the class.
In essence, when a member is declared static, it belongs to the class itself, rather than to any specific instance (object) of that class. This means that a static member is shared by all objects of that class. Let's break this down.
1. Static Variables (Class Variables)
A static variable is also known as a class variable. Unlike instance variables (which belong to each object), a single copy of a static variable is created and shared among all instances of the class.
Key Characteristics:
Belongs to the class: You access it using the class name, not an object reference (e.g.,
ClassName.staticVariable).One copy: All objects of the class share the same static variable. If one object changes it, the change is reflected for all other objects.
Memory allocation: Static variables are allocated memory only once when the class is loaded into memory.
When to use them:
When you need a variable that is common to all objects of a class.
For constants that are shared across all instances (e.g.,
Math.PI).For counters that track the number of objects created.
Example:
Consider a scenario where you want to keep track of the total number of students created in a system, or a common school name.
public class Student {
// Instance variable: Each student object will have its own name
String name;
// Static variable: Shared by all Student objects
static String schoolName = "Tech High School";
// Static variable: Counter for the number of students created
static int studentCount = 0;
public Student(String name) {
this.name = name;
studentCount++; // Increment static counter each time a new student is created
}
public void displayStudentInfo() {
System.out.println("Student Name: " + this.name);
System.out.println("School: " + Student.schoolName); // Access static variable using class name
System.out.println("Total Students (so far): " + Student.studentCount);
System.out.println("---");
}
public static void main(String[] args) {
// Accessing static variable before creating any objects
System.out.println("Initial Student Count: " + Student.studentCount);
System.out.println("School Name: " + Student.schoolName);
System.out.println("---");
Student s1 = new Student("Alice");
s1.displayStudentInfo();
Student s2 = new Student("Bob");
s2.displayStudentInfo();
// We can change the static variable through the class name or any object (though class name is preferred)
Student.schoolName = "Global Academy";
System.out.println("School name changed to: " + Student.schoolName);
System.out.println("---");
Student s3 = new Student("Charlie");
s3.displayStudentInfo(); // All students now reflect the new school name
System.out.println("Final Student Count: " + Student.studentCount);
}
}
Explanation:
schoolNameandstudentCountarestatic. They belong to theStudentclass.When
s1,s2, ands3are created, they all share the samestudentCountandschoolName.Changing
Student.schoolNameaffects all instances.
2. Static Methods (Class Methods)
A static method is also known as a class method. These methods belong to the class rather than any specific object. You can call them directly using the class name, without creating an instance of the class.
Key Characteristics:
Belongs to the class: You call it using
ClassName.staticMethod().Cannot use
thisorsuper: Static methods operate independently of any specific object, so they cannot refer to instance variables or instance methods directly usingthisorsuperkeywords.Can only access static members: A static method can directly call other static methods and access static variables of the same class. To access instance members, you would need an object reference.
Memory allocation: Static methods are loaded into memory along with the class.
When to use them:
Utility methods that perform operations not dependent on any particular object's state (e.g.,
Math.max(),Integer.parseInt()).Methods that only need to access static variables.
Factory methods that return an instance of the class.
Example:
Let's add a utility method to our Student class that doesn't need a specific student object to perform its function.
public class Calculator {
// Static method for addition
public static int add(int a, int b) {
return a + b;
}
// Static method to display a generic message
public static void displayWelcomeMessage() {
System.out.println("Welcome to the Calculator!");
}
public static void main(String[] args) {
// Calling static methods using the class name
Calculator.displayWelcomeMessage();
int sum = Calculator.add(10, 5);
System.out.println("Sum: " + sum);
int product = multiply(7, 8); // Can call static method directly within the same class's static method
System.out.println("Product: " + product);
// Attempting to call a non-static method or access a non-static variable directly would cause an error
// int x = nonStaticVar; // Error: Cannot make a static reference to the non-static field nonStaticVar
// nonStaticMethod(); // Error: Cannot make a static reference to the non-static method nonStaticMethod()
}
// Another static method
public static int multiply(int a, int b) {
return a * b;
}
// Non-static (instance) variable and method for demonstration of restrictions
// int nonStaticVar = 100;
// public void nonStaticMethod() {
// System.out.println("This is a non-static method.");
// }
}
Explanation:
add()anddisplayWelcomeMessage()arestaticmethods.They are called directly using
Calculator.add()andCalculator.displayWelcomeMessage().Notice how
multiply()is called directly withinmain()because both are static methods within the same class.
3. Static Blocks
A static block is a special block of code that is executed only once when the class is loaded into memory. It's primarily used for initializing static variables.
Key Characteristics:
Execution: Executed exactly once when the class is first loaded.
Purpose: Primarily used to initialize static variables that require some logic (e.g., reading from a file, performing complex calculations).
Placement: Can appear anywhere within the class.
Example:
public class ApplicationSettings {
static String appVersion;
static String databaseConnectionUrl;
static int maxConnections;
// Static block for initializing static variables
static {
System.out.println("Static block executed: Initializing application settings...");
appVersion = "1.0.0";
databaseConnectionUrl = "jdbc:mysql://localhost:3306/appdb";
maxConnections = 50;
// You could perform more complex initialization here, like reading from a config file
System.out.println("Settings initialized successfully.");
System.out.println("--------------------");
}
public static void displaySettings() {
System.out.println("Application Version: " + appVersion);
System.out.println("Database URL: " + databaseConnectionUrl);
System.out.println("Max Connections: " + maxConnections);
System.out.println("--------------------");
}
public static void main(String[] args) {
System.out.println("Main method started.");
// The static block will execute before this line if the class hasn't been loaded yet.
ApplicationSettings.displaySettings(); // Accessing a static method will trigger class loading
// If we access a static variable directly, it also triggers class loading (and thus static block execution)
System.out.println("App Version from direct access: " + ApplicationSettings.appVersion);
// Creating an object also triggers static block if not already executed
// ApplicationSettings settings = new ApplicationSettings();
}
}
Explanation:
The code inside the
static { ... }block runs as soon asApplicationSettingsclass is loaded. This happens when you first try to access any static member ofApplicationSettings(likeApplicationSettings.displaySettings()orApplicationSettings.appVersion), or when you create the first object of this class.
4. Static Nested Classes
Java also allows you to define a class inside another class. When a nested class is declared static, it's called a static nested class.
Key Characteristics:
No outer object dependency: A static nested class does not require an instance of its outer class to be created. It behaves like a top-level class.
Access to outer members: It can only access static members of the outer class directly. To access non-static members of the outer class, it needs an instance of the outer class.
Use cases: Often used to group related classes that only make sense together, without implicitly linking the inner class to an outer object's state.
Example (Conceptual - typically covered in more advanced topics):
class OuterClass {
static int outerStaticVar = 10;
int outerInstanceVar = 20;
static class StaticNestedClass {
void display() {
System.out.println("From Static Nested Class:");
System.out.println("Outer Static Var: " + OuterClass.outerStaticVar);
// System.out.println("Outer Instance Var: " + outerInstanceVar); // ERROR: Cannot access non-static member directly
}
}
public static void main(String[] args) {
OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
nested.display();
}
}
Explanation:
StaticNestedClassis astaticnested class insideOuterClass.You can create an instance of
StaticNestedClasswithout creating an instance ofOuterClass.It can access
outerStaticVardirectly because it's static, but notouterInstanceVardirectly.
Key Takeaways
staticmeans "belongs to the class," not to an object.Static variables are shared by all objects of the class (one copy for the entire class).
Static methods can be called using the class name and cannot directly access instance members (variables or methods) of the same class without an object.
Static blocks are executed once when the class is loaded, typically for static member initialization.
main()method is alwaysstaticbecause it needs to be called by the Java Virtual Machine (JVM) without creating an object of your class.
Exercise
To solidify your understanding, try the following exercise:
Problem: Create a Java class called BankAccount with the following:
An instance variable
accountNumber(String).An instance variable
balance(double).A static variable
nextAccountNumber(int) initialized to1001. This variable should automatically assign a uniqueaccountNumberto each newBankAccountobject.A static variable
totalAccountsCreated(int) to keep track of how many bank accounts have been created.A constructor that takes an initial
balance, assignsnextAccountNumberas theaccountNumberto the new account, and then incrementsnextAccountNumberandtotalAccountsCreated.An instance method
deposit(double amount)that adds the amount to the balance.An instance method
withdraw(double amount)that subtracts the amount from the balance (ensure balance doesn't go below zero).An instance method
getAccountInfo()that prints theaccountNumberandbalancefor that specific account.A static method
displayTotalAccounts()that prints the total number of accounts created usingtotalAccountsCreated.
Instructions:
Write the
BankAccountclass.In a
mainmethod (which must bestatic), create at least threeBankAccountobjects.Perform some deposits and withdrawals on these accounts.
Call
getAccountInfo()for each account.Finally, call the
displayTotalAccounts()static method to see the total.
Good luck! This exercise will help you distinguish between static and instance members and understand their practical applications.
Key Takeaways
-
It means a member belongs to the class itself, not to any specific object (instance) of that class
-
There's only one copy of a static variable, shared by all objects of the class. Changes to it are seen by everyone.
-
These methods are called using the class name (e.g., ClassName.staticMethod()). They cannot directly access instance (non-static) variables or methods without an object reference.
-
Code inside a static block executes only once when the class is first loaded into memory, usually for initializing static variables.
-
It's static because the Java Virtual Machine (JVM) needs to call it without creating an object of your class.