
Naming conventions make code readable. When every Java developer follows the same patterns, you can glance at a name and immediately know whether it’s a class, a variable, a constant, or a method. You don’t have to think about it.
Java’s conventions have been stable since the 1990s. They’re documented in Oracle’s Code Conventions and reinforced by every IDE, linter, and code review. Following them isn’t optional if you want to write professional code.
Classes and Interfaces
Class names use PascalCase (also called UpperCamelCase). Each word starts with a capital letter, with no underscores or hyphens.
// Correct
public class CustomerAccount { }
public class HttpRequestHandler { }
public class XMLParser { }
// Wrong
public class customerAccount { } // starts lowercase
public class Customer_Account { } // underscore
public class CUSTOMERACCOUNT { } // all caps
Class names should be nouns or noun phrases. They represent things: a User, an OrderProcessor, a DatabaseConnection. Avoid verbs for class names.
Interface names follow the same PascalCase convention. Some developers prefix interfaces with “I” (like IComparable), but this isn’t standard Java practice. Java’s built-in interfaces don’t use prefixes: List, Map, Comparable, Serializable.
// Standard Java style
public interface Drawable { }
public interface PaymentProcessor { }
// C# style - not typical in Java
public interface IDrawable { } // Avoid this
Some interfaces describe capabilities and use adjectives ending in “-able” or “-ible”: Runnable, Callable, Comparable, Serializable. Others are nouns: List, Map, Observer.
Methods
Method names use camelCase. The first word is lowercase, and each subsequent word starts with a capital letter.
// Correct
public void calculateTotal() { }
public String getUserName() { }
public boolean isValid() { }
// Wrong
public void CalculateTotal() { } // PascalCase
public void calculate_total() { } // snake_case
Methods represent actions, so their names should be verbs or verb phrases: calculate, send, process, validate, convert.
Getters and setters follow specific patterns. A getter for a field named email should be getEmail(). A setter should be setEmail(). For boolean fields, getters often use is instead of get: isActive(), isEnabled(), hasPermission().
public class User {
private String email;
private boolean active;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
Factory methods often start with create, new, or of: createInstance(), newBuilder(), of(). Conversion methods use to: toString(), toArray(), toList().
Variables
Local variables and instance fields use camelCase, just like methods.
// Correct
int itemCount = 0;
String firstName = "Alice";
List<Order> pendingOrders = new ArrayList<>();
// Wrong
int ItemCount = 0; // PascalCase
int item_count = 0; // snake_case
int ITEMCOUNT = 0; // all caps (reserved for constants)
Variable names should be descriptive. Single-letter names are acceptable only in very limited contexts: loop counters (i, j, k), coordinates (x, y), or caught exceptions (e).
// Acceptable short names
for (int i = 0; i < items.length; i++) { }
try {
// ...
} catch (IOException e) {
logger.error("Read failed", e);
}
// But prefer descriptive names elsewhere
int numberOfRetries = 3; // Not: int n = 3;
String customerEmail = input; // Not: String s = input;
Boolean variables often read as questions or assertions: isReady, hasError, canProceed, shouldRetry.
Constants
Constants use SCREAMING_SNAKE_CASE. All letters are uppercase, with underscores separating words.
public static final int MAX_RETRY_COUNT = 3;
public static final String DEFAULT_ENCODING = "UTF-8";
public static final double TAX_RATE = 0.08;
// Wrong
public static final int maxRetryCount = 3; // camelCase
public static final int MaxRetryCount = 3; // PascalCase
This convention applies to static final fields that are truly constant. If a static final reference points to a mutable object, some developers use camelCase to indicate that the contents can change even though the reference cannot.
// Immutable - use SCREAMING_SNAKE_CASE
public static final String API_VERSION = "2.0";
public static final List<String> VALID_CODES = List.of("A", "B", "C");
// Mutable contents - some prefer camelCase
public static final List<String> registeredUsers = new ArrayList<>();
// Or make it clearly constant by using an immutable collection
Enum constants also use SCREAMING_SNAKE_CASE:
public enum OrderStatus {
PENDING,
PROCESSING,
SHIPPED,
DELIVERED,
CANCELLED
}
Packages
Package names are all lowercase with no underscores. They typically start with a reversed domain name to ensure uniqueness.
// Correct
package com.javaking.tutorials;
package org.apache.commons.lang3;
package java.util.concurrent;
// Wrong
package com.JavaKing.Tutorials; // Mixed case
package com.java_king.tutorials; // Underscores
Package names should be short and descriptive. Avoid overly deep hierarchies. Three to four levels is usually enough: com.company.project.module.
Generics
Type parameters use single uppercase letters. The most common conventions:
// E - Element (used in collections)
public interface List<E> { }
// K, V - Key and Value (used in maps)
public interface Map<K, V> { }
// T - Type (general purpose)
public class Box<T> { }
// S, U, V - Second, Third, Fourth types when you need multiple
public class Pair<T, U> { }
// N - Number
public class Calculator<N extends Number> { }
// R - Return type
public interface Function<T, R> { }
These single-letter names are the one place where Java encourages non-descriptive naming. The brevity distinguishes type parameters from actual class names at a glance.
Common Naming Patterns
Certain prefixes and suffixes have established meanings in Java.
Abstract classes often include “Abstract” in the name: AbstractList, AbstractMap, AbstractController. This makes the inheritance hierarchy obvious.
Implementations sometimes include “Impl” when implementing an interface with no better name: UserServiceImpl, PaymentProcessorImpl. But if a more descriptive name exists, prefer that: ArrayList implements List, HashSet implements Set.
Exceptions always end with “Exception”: IllegalArgumentException, FileNotFoundException, CustomValidationException.
Test classes end with “Test”: UserServiceTest, OrderProcessorTest. Test methods in JUnit 5 can use descriptive names with underscores or spaces: should_throw_exception_when_input_is_null() or @DisplayName("throws exception when input is null").
// Production code
public class OrderService { }
public class InvalidOrderException extends RuntimeException { }
// Test code
public class OrderServiceTest {
@Test
void processOrder_validInput_returnsOrder() { }
@Test
void processOrder_nullCart_throwsException() { }
}
What to Avoid
Hungarian notation prefixes variable names with type abbreviations: strName, intCount, boolIsValid. This was common in older languages but is unnecessary in Java, where IDEs show types on hover.
// Avoid Hungarian notation
String strFirstName; // Just use: firstName
int intOrderCount; // Just use: orderCount
boolean boolIsActive; // Just use: isActive
Abbreviations hurt readability. Write customerAddress, not custAddr. Write numberOfItems, not numItms. The extra characters cost nothing but save confusion.
Standard abbreviations that everyone recognizes are fine: URL, HTTP, XML, ID, HTML. Use them in their conventional form: userId (not userID), httpRequest, parseXml.
Meaningless names like data, info, temp, value, or result tell you nothing. What kind of data? What information? Be specific: userData, orderInfo, validationResult.
// Vague
Object data = fetchData();
String temp = process(input);
int result = calculate(values);
// Clear
User currentUser = fetchUserById(userId);
String formattedAddress = formatAddress(rawAddress);
int totalPrice = calculateOrderTotal(lineItems);
IDE Support
Modern IDEs enforce naming conventions automatically. IntelliJ IDEA, Eclipse, and VS Code all highlight violations and can generate properly-named code.
When you create a getter method, the IDE suggests getFieldName(). When you extract a constant, it suggests SCREAMING_SNAKE_CASE. When you rename a class, it offers to rename the file to match.
Configure your IDE’s inspection settings to warn about naming violations. Catching these issues during development is easier than fixing them in code review.
Quick Reference
| Element | Convention | Example |
|---|---|---|
| Class | PascalCase | CustomerOrder |
| Interface | PascalCase | PaymentProcessor |
| Method | camelCase | calculateTotal() |
| Variable | camelCase | itemCount |
| Constant | SCREAMING_SNAKE_CASE | MAX_SIZE |
| Package | lowercase | com.example.util |
| Type Parameter | Single uppercase | T, E, K, V |
| Enum Constant | SCREAMING_SNAKE_CASE | ORDER_PENDING |
Consistency matters more than any individual rule. When joining an existing project, follow its established patterns even if they differ slightly from standard conventions. Readable code is code that follows predictable patterns throughout.
Related: Java Classes and Objects | Java Methods | Best Java IDEs Compared
Sources
- Oracle. “Code Conventions for the Java Programming Language.” oracle.com/technetwork/java
- Google. “Google Java Style Guide.” google.github.io/styleguide/javaguide.html
- Bloch, Joshua. “Effective Java.” 3rd Edition, 2018


