DEV Community

Mayur Bodhare
Mayur Bodhare

Posted on

Read Java Code Faster: Naming Conventions Decoded

Here's something that confused me when I started: I could name my class bank_account, my method Withdraw and my variable Bal, and Java compiled it all without a single complaint. So why does everyone keep telling beginners to follow "naming conventions"?

The answer is that Java doesn't care, but people do. Code is read far more often than it is written, and the names are the first thing a reader sees. A shared naming style lets you look at a word and know what kind of thing it is before you read a single line around it.

In this post, we'll go through the naming conventions Java developers follow, why each one exists, and what the compiler does (and doesn't) enforce.

Rules vs conventions

These two get mixed up, so let's separate them first.

Rules are enforced by the compiler. Break one and your code won't compile. For names:

  • A name can contain letters, digits, underscores _ and dollar signs $.
  • It cannot start with a digit.
  • It cannot be a Java keyword like class, int or static.
  • It's case-sensitive, so count, Count and COUNT are three different names.
  • No spaces.
int studentCount = 5;   // valid
int _temp = 1;          // valid, but avoid it
int $price = 10;        // valid, but avoid it
int 2ndPlace = 2;       // compile error: starts with a digit
int class = 3;          // compile error: keyword
Enter fullscreen mode Exit fullscreen mode

Conventions are habits the whole Java community agrees on. The compiler ignores them, but your teammates, your future self and every code reviewer won't. The main sources are Oracle's old code conventions and the popular Google Java Style Guide, and they agree on almost everything.

There's one naming rule that surprises people: a public class must live in a file with the same name. A public class Student must be in Student.java, or you get:

class Student is public, should be declared in a file named Student.java
Enter fullscreen mode Exit fullscreen mode

The big picture: three casing styles

Almost everything in Java uses one of three styles. Let's name them so we can use them below:

  • PascalCase (also called UpperCamelCase): every word starts with a capital letter, with no separators. Example: BankAccount.
  • camelCase (also called lowerCamelCase): the first word is lowercase, every later word starts with a capital. Example: bankBalance.
  • UPPER_SNAKE_CASE: all capitals, words separated by underscores. Example: MAX_SIZE.

Now let's see where each one goes.

Classes and interfaces: PascalCase

Classes and interfaces start with a capital letter, and every new word does too. Use nouns for classes, because a class represents a thing.

class Student { }
class BankAccount { }
class HttpServer { }
Enter fullscreen mode Exit fullscreen mode

Interfaces follow the same casing. They're often named as a noun (List, Map) or as an ability, usually ending in "-able" (Runnable, Comparable, Serializable).

interface Flyable { }
interface PaymentGateway { }
Enter fullscreen mode Exit fullscreen mode

A few notes that save you from common debates:

  • Don't prefix interfaces with I. Some other languages write IList. Java doesn't. The standard library has List, not IList.
  • Name implementations by what makes them special. The interface is List, and the implementations are ArrayList and LinkedList. Compare that with a lazy ListImpl, which says nothing. (UserServiceImpl is common in real projects, and it's acceptable, but a descriptive name is better when you can find one.)
  • Acronyms: modern style treats them like words, so HttpServer and XmlParser rather than HTTPServer and XMLParser. Whatever you pick, stay consistent.
  • Special endings: exceptions end with Exception (InvalidAgeException), and abstract base classes in the standard library often start with Abstract (AbstractList).

Methods: camelCase, starting with a verb

A method does something, so its name should read like an action: lowercase first word, then camelCase.

void calculateTotal() { }
void sendEmail() { }
String getName() { }
Enter fullscreen mode Exit fullscreen mode

Some common patterns:

  • Getters and setters: getName(), setName(String name).
  • Boolean methods read like a yes/no question: isEmpty(), hasNext(), canEdit().
  • Conversions: toString(), toArray().

The getX and setX pattern isn't just style. Many frameworks and libraries find your data by looking for exactly those names, so in practice it's close to a rule.

Variables: camelCase, with meaningful names

Variables follow the same style as methods: lowercase first word, then camelCase. Unlike methods, they're usually nouns.

int studentCount = 30;
String firstName = "Asha";
double averageMarks = 82.5;
Enter fullscreen mode Exit fullscreen mode

A few habits that make a big difference:

  • Booleans read as true or false statements: isActive, hasAccess, canVote.
  • Collections get plural names: students, orderIds. Then for (Student student : students) reads like English.
  • Single letters are fine only in tiny scopes, like the loop counters i and j. For anything else, use a real word.
  • Avoid _ and $ in names. They're legal, but they're not the Java style (that's snake_case from other languages).

Constants: UPPER_SNAKE_CASE

A constant is a value that never changes. In Java, that means a static final field. By convention it's written in all capitals, with underscores between words:

static final int MAX_LOGIN_ATTEMPTS = 3;
static final double TAX_RATE = 0.18;
static final String DEFAULT_CITY = "Pune";
Enter fullscreen mode Exit fullscreen mode

The standard library does this too: Integer.MAX_VALUE, Math.PI.

Two small details:

  • Name the constant for its meaning, not its value. MAX_LOGIN_ATTEMPTS is useful. THREE is not, because when the rule changes to 5, the name lies.
  • UPPER_CASE is for true constants only. A plain final local variable or a final instance field is just a normal variable, so it stays in camelCase. And a static final list that you keep adding items to isn't really constant, so avoid shouting at it in capitals.

Packages: all lowercase

A package groups related classes, like folders group files. Package names are all lowercase, no underscores, and they usually start with a reversed domain name so they're unique worldwide:

package com.example.shop.orders;
Enter fullscreen mode Exit fullscreen mode

This one has a behind-the-scenes effect: the package name has to match the folder structure. The file above must sit in com/example/shop/orders/. That's how the JVM finds your class, by turning com.example.shop.orders.Order into a file path.

Enums, generics and annotations

  • Enum types are PascalCase, and their values are UPPER_SNAKE_CASE (they're constants):
enum Day {
    MONDAY, TUESDAY, WEDNESDAY
}
Enter fullscreen mode Exit fullscreen mode
  • Generic type parameters are a single capital letter: T for type, E for element, K and V for key and value, N for number.
class Box<T> { }
Map<K, V> map;
Enter fullscreen mode Exit fullscreen mode
  • Annotations are PascalCase: @Override, @FunctionalInterface.

A quick cheat sheet

  • Class: StudentRecord
  • Interface: Comparable, PaymentGateway
  • Method: calculateTotal()
  • Variable: studentCount
  • Constant: MAX_SIZE
  • Package: com.example.shop
  • Enum type and values: Day.MONDAY
  • Generic type: T, E, K, V

Why this matters: reading code at a glance

Here's the payoff. Look at a line you've written dozens of times:

System.out.println("Hi");
Enter fullscreen mode Exit fullscreen mode
   System  .  out  .  println ( "Hi" )
     |         |        |
   class    variable  method
 (Pascal)  (camel)   (camel)
Enter fullscreen mode Exit fullscreen mode

Without knowing anything about the standard library, you can already tell that System is a class, because it starts with a capital letter, and that out and println are not classes. The same works for Integer.MAX_VALUE: Integer is a class, and MAX_VALUE is a constant.

This is what conventions buy you. Your eyes do the classification for you.

Same code, two naming styles

Here is a small program that follows the conventions:

public class BankAccount {
    private static final int MAX_WITHDRAW_LIMIT = 1000;

    private int balance;

    public BankAccount(int initialBalance) {
        this.balance = initialBalance;
    }

    public boolean withdraw(int amount) {
        if (amount > MAX_WITHDRAW_LIMIT || amount > balance) {
            return false;
        }
        balance -= amount;
        return true;
    }

    public int getBalance() {
        return balance;
    }

    public static void main(String[] args) {
        BankAccount account = new BankAccount(5000);
        System.out.println(account.withdraw(400));
        System.out.println(account.withdraw(1500));
        System.out.println(account.getBalance());
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

true
false
4600
Enter fullscreen mode Exit fullscreen mode

And here's the same program with the conventions ignored (it goes in bank_account.java):

public class bank_account {
    static final int maxlimit = 1000;
    int Bal;

    bank_account(int b) { Bal = b; }

    boolean Withdraw(int a) {
        if (a > maxlimit || a > Bal) return false;
        Bal -= a;
        return true;
    }

    public static void main(String[] args) {
        bank_account Acc = new bank_account(5000);
        System.out.println(Acc.Withdraw(400));
        System.out.println(Acc.Withdraw(1500));
        System.out.println(Acc.Bal);
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

true
false
4600
Enter fullscreen mode Exit fullscreen mode

Exactly the same output. The compiler is perfectly happy. But now read Acc.Withdraw(400). With that capital A and capital W, it looks like a class calling a static method, even though Acc is an object. And what is a? What is b? What is Bal? You have to dig through the code to find out. Multiply that by a project with 500 files and you see why teams care.

Beyond casing: what makes a name good

Casing is the easy part. The harder skill is choosing the words:

  • Be descriptive. studentCount beats cnt, and calculateTax() beats calc().
  • Longer scope, more descriptive. A loop counter can be i. A field used all over the class deserves a full name.
  • Don't lie. A variable named accountList that holds a Set will confuse everyone. A method named getUser() that also deletes something is a trap.
  • Avoid type prefixes like strName or intAge. The type is already visible in the declaration, and your IDE shows it too.
  • Prefer positive booleans. isActive is easier to think about than isNotActive, especially in if (!isNotActive).
  • Avoid names that differ by one character, like data1 and datal, or the letters l and O, which look like 1 and 0.

Which style should I follow?

Since the conventions are mostly settled, the real questions are about the gray areas:

  • Short name or long name? Pick the longer, clearer one. Nobody pays you per character, and your IDE autocompletes it anyway.
  • Impl suffix or a descriptive name? Use a descriptive name if one exists (ArrayList). Use Impl only when there's truly nothing special to say.
  • Your own style or the team's style? Always follow the project's existing style, even if you prefer another. Consistency beats personal taste.
  • Do it by hand or use tools? Use tools. IDEs like IntelliJ IDEA and Eclipse have a rename refactoring that safely changes a name everywhere. Linters like Checkstyle can flag convention breaks automatically.

Common mistakes

  1. Starting a method or variable with a capital letter. Withdraw() and Bal look like classes. Use withdraw() and balance.
  2. Using snake_case. student_count is the style of other languages. In Java, it's studentCount.
  3. Writing every final variable in UPPER_CASE. That style is for true constants (static final). A normal final local variable stays camelCase.
  4. Cryptic names. a, x1, temp2, data and flag say nothing. Use names that explain the purpose.
  5. Borrowing habits from other languages. No I prefix on interfaces, and no Hungarian notation like strName.
  6. Misleading or negative names. isNotActive, or a method called getTotal() that also changes data. A name is a promise, so keep it.

Quick recap

  • The compiler enforces rules (no leading digit, no keywords, case-sensitive, file name matches the public class) and ignores conventions.
  • Classes and interfaces: PascalCase, usually nouns (BankAccount, Comparable).
  • Methods: camelCase, starting with a verb (calculateTotal, isEmpty).
  • Variables: camelCase, meaningful nouns (studentCount).
  • Constants: UPPER_SNAKE_CASE, for static final values (MAX_SIZE).
  • Packages: all lowercase, reverse domain (com.example.shop).
  • Enums: PascalCase type, UPPER_SNAKE_CASE values. Generics: a single capital letter.
  • Good names are descriptive, honest and consistent with the team.

Try it yourself

Here's a small practice idea: find an old program of yours (or any beginner code online) and clean up the names. Fix the casing first, then replace every cryptic name with a descriptive one. Use your IDE's rename feature so nothing breaks. Then read the code out loud. If it reads like a sentence, you've done it right.

For a bonus, open a few classes from the standard library in your IDE and look at how they're named. Notice the patterns: Runnable, ArrayList, Integer.MAX_VALUE. You'll start spotting the conventions everywhere.

If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.

Top comments (0)