Understanding the Static Keyword in Java: A Practical Example
Written on
Chapter 1: Encountering the Static Keyword
This Tuesday at work, I came across an intriguing scenario involving the static keyword in Java that I thought would be worthwhile to share.
Scenario
Within an OrderService class, we maintain a HashMap that holds information about order items. The class includes a put() method that accepts an Order object and adds it to the map. For clarity, we will use orderId as the key and itemId as the value.
public class OrderService {
private final Map<String, String> orderItemMap = new HashMap<>();
// Class constructor
public void put(Order order) {
orderItemMap.put(order.getOrderId(), order.getItemId());}
}
private class Order {
String orderId;
String itemId;
// Getters and setters
}
Later in the afternoon, my colleague introduced a new method called load() in the OrderService class. This method accepts a list of Order objects and iterates through them to call the put() method, effectively storing the orderId-itemId pairs in the map.
public void load(List<Order> orders) {
orders.forEach(OrderService::put);
}
At first glance, this approach seems reasonable, right? My colleague employed a Java functional programming technique to enhance code brevity, steering clear of a cumbersome while loop for list iteration. For those interested in improving their functional programming skills, I recommend checking out my article on the topic.
Java Coding Tip — Functional Programming
Returning to the situation at hand, in the same code commit, my colleague added the static keyword to the put method and the map object.
private static final Map<String, String> orderItemMap = new HashMap<>();
public static void put(Order order) {
orderItemMap.put(order.getOrderId(), order.getItemId());
}
Upon reviewing the new code, I was puzzled as to why the static keyword was applied. The orderItemMap should be specific to each instance of OrderService. By making it static, all instances would share the same map.
With Static Keyword
Without Static Keyword
To explore this further, I decided to remove the static keywords from both the orderItemMap field and the put method. However, this led to the following error:
The error stated: “Non-static method cannot be referenced from a static context.” But why does this occur?
In my colleague's commit, while iterating over the list of orders, it referenced the put() method in the OrderService class. Since OrderService is the "main" class in the classpath, the method reference assumes that the put() method can be called without any instances of OrderService being created. IntelliJ IDE suggests adding the static keyword to the put method and the map field, which explains the recent code changes.
How to Resolve the Issue?
Recognizing that both the map field and the put method are specific to instances, we need to reference them from an instance of the OrderService class rather than the main class itself. The solution is to change the method reference from OrderService to this keyword:
The this keyword points to the current instance of the class. Consequently, the put method is now called from the instance context of OrderService, allowing us to avoid introducing static keywords elsewhere.
I hope this article proves useful. If you are on a journey to learn Java and delve deeper into backend engineering or simply wish to reflect on your work and life regularly, feel free to follow my channel for insights from my daily experiences.
Additional Reading:
- A Glimpse into Bytecode Conversion to Class Objects in the JVM
- Automating Repetitive Java Code to Enhance Efficiency