Static Fields and Constants
Use static fields for shared state, constants with static final, and static initializers.
Static Fields and Constants is a free Java Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Static Fields and Constants
Static fields belong to the class, not to instances. They are shared across all objects of the class. Constants combine static and final to create class-level immutable values.
Static vs Instance Fields
An instance field has a separate copy per object. A static field has one copy shared by all objects of the class.
class Counter {
private static int totalCount = 0; // shared across all instances
private int instanceId; // unique per instance
Counter() {
totalCount++;
instanceId = totalCount;
}
static int getTotalCount() { return totalCount; }
int getInstanceId() { return instanceId; }
}
Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();
System.out.println(Counter.getTotalCount()); // 3
System.out.println(c1.getInstanceId()); // 1
System.out.println(c3.getInstanceId()); // 3Constants with static final
Declare constants as public static final. By convention they use SCREAMING_SNAKE_CASE.
class MathConstants {
public static final double PI = 3.141592653589793;
public static final double E = 2.718281828459045;
public static final double GOLDEN = 1.618033988749895;
public static final int PRIMES[] = {2, 3, 5, 7, 11, 13};
}
// Access without an instance
System.out.println(MathConstants.PI);
// Constants on domain classes
class HttpStatus {
public static final int OK = 200;
public static final int NOT_FOUND = 404;
public static final int SERVER_ERR = 500;
}Static Initializer Blocks
When a constant requires complex initialization, use a static initializer block that runs once when the class is loaded.
import java.util.*;
class Config {
public static final Map<String, String> DEFAULTS;
static {
Map<String, String> map = new HashMap<>();
map.put("timeout", "30");
map.put("maxRetry", "3");
map.put("logLevel", "INFO");
DEFAULTS = Collections.unmodifiableMap(map);
}
}
System.out.println(Config.DEFAULTS.get("timeout")); // 30Static Counter Pattern
Static fields are commonly used for ID generation, metrics counting, or shared caches.
import java.util.concurrent.atomic.AtomicLong;
class Order {
private static final AtomicLong ID_SEQUENCE = new AtomicLong(1000);
private final long id;
private final String item;
Order(String item) {
this.id = ID_SEQUENCE.getAndIncrement();
this.item = item;
}
long getId() { return id; }
String getItem() { return item; }
}
Order o1 = new Order("Laptop");
Order o2 = new Order("Mouse");
System.out.println(o1.getId()); // 1000
System.out.println(o2.getId()); // 1001Singleton via Static Field
A static field holds the single instance in a Singleton. Use lazy initialization for classes that might not always be needed.
class DatabasePool {
private static volatile DatabasePool instance;
private final int maxConnections;
private DatabasePool() { this.maxConnections = 20; }
public static DatabasePool getInstance() {
if (instance == null) {
synchronized (DatabasePool.class) {
if (instance == null)
instance = new DatabasePool();
}
}
return instance;
}
public int getMaxConnections() { return maxConnections; }
}
System.out.println(DatabasePool.getInstance().getMaxConnections()); // 20Static Import
import static lets you use static members without the class name prefix — useful for constants and utility methods.
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;
// Without import static: Math.PI * Math.pow(r, 2)
double radius = 5.0;
double area = PI * pow(radius, 2);
System.out.printf("Area: %.2f%n", area); // 78.54
// Caution: overuse of static imports hurts readability
// Acceptable for: Math.*, Assert.* in tests, TimeUnitThread Safety of Static Fields
Static fields shared across threads require synchronization or atomic types to avoid race conditions.
import java.util.concurrent.atomic.*;
class RequestMetrics {
private static final AtomicLong requestCount = new AtomicLong(0);
private static final AtomicLong totalLatencyMs = new AtomicLong(0);
public static void record(long latencyMs) {
requestCount.incrementAndGet();
totalLatencyMs.addAndGet(latencyMs);
}
public static double averageLatency() {
long count = requestCount.get();
return count == 0 ? 0 : (double) totalLatencyMs.get() / count;
}
}
RequestMetrics.record(45);
RequestMetrics.record(120);
System.out.println(RequestMetrics.averageLatency()); // 82.5Mutable Static Fields: Pitfalls
Mutable static fields are dangerous: global mutable state is hard to test, thread-unsafe without care, and creates hidden coupling between classes.
// BAD: mutable static state
class GlobalConfig {
public static String environment = "dev"; // mutable global!
}
// Any code anywhere can change GlobalConfig.environment
// Very hard to test, unexpected interactions
// BETTER: immutable constant
class GlobalConfig2 {
public static final String ENVIRONMENT =
System.getenv().getOrDefault("APP_ENV", "dev");
}
// BEST: inject via constructor (dependency injection)
class Service {
private final String environment;
Service(String environment) { this.environment = environment; }
}Constants Interface Anti-Pattern
Using an interface to hold constants (the "Constant Interface" anti-pattern) is discouraged. Use a class with a private constructor instead.
// BAD: constant interface — pollutes the namespace of implementing classes
interface FinancialConstants {
double TAX_RATE = 0.08; // implicitly public static final
}
// GOOD: utility class for constants
final class FinancialConstants2 {
private FinancialConstants2() {} // prevent instantiation
public static final double TAX_RATE = 0.08;
public static final double VAT_RATE = 0.20;
public static final int MAX_ITEMS = 100;
}
System.out.println(FinancialConstants2.TAX_RATE); // 0.08Practical: Feature Flags via Constants
Using static final boolean constants for compile-time feature flags — the JIT compiler eliminates dead branches.
class Features {
public static final boolean ENABLE_ANALYTICS = true;
public static final boolean ENABLE_AI_SEARCH = false;
public static final boolean DEBUG_MODE =
"true".equals(System.getenv("DEBUG"));
}
// The JIT eliminates this if-block when ENABLE_AI_SEARCH is false:
if (Features.ENABLE_AI_SEARCH) {
System.out.println("Running AI search...");
}
if (Features.DEBUG_MODE) {
System.out.println("[DEBUG] Request received");
}Quick Check
What is the difference between a static field and an instance field?
Recap: Static Fields and Constants
Key takeaways:
- Static fields belong to the class — one copy shared by all instances
- Constants: public static final UPPER_SNAKE_CASE
- Use static initializer blocks for constants requiring complex initialization
- Prefer AtomicLong/AtomicInteger for mutable static fields in concurrent code
- Avoid mutable static fields — they create hidden global state that is hard to test
- Use a non-instantiable class (private constructor) for constants instead of an interface
Frequently asked questions
Is the “Static Fields and Constants” lesson free?
Yes — the full text of “Static Fields and Constants” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Static Fields and Constants”?
Use static fields for shared state, constants with static final, and static initializers. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Static Fields and Constants” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Method Overloading Rules
- Varargs Parameters
- Static Fields and Constants
- Utility Classes and Static Factory Methods