Why Naming Matters
Code is read far more often than it is written. The names you choose for classes, methods, variables, and constants are the first layer of documentation your teammates encounter. Good names eliminate the need for comments, reduce onboarding time, and prevent bugs caused by misunderstanding what a piece of code does.
As Phil Karlton famously said: “There are only two hard things in Computer Science: cache invalidation and naming things.”
Let’s walk through the naming conventions every professional developer should follow, with examples in Java and Python.
Class and Type Naming
Classes represent things — entities, services, concepts. Use PascalCase (every word capitalized, no underscores). The name should be a noun or noun phrase that clearly describes what the class represents.
// Java - Good
public class UserAccount { }
public class PaymentProcessor { }
public class HttpRequestHandler { }
// Bad
public class useraccount { } // no casing
public class Mgr { } // cryptic abbreviation
public class DataStuff { } // vague# Python - Same convention for classes
class UserAccount:
pass
class PaymentProcessor:
pass
# Bad
class user_account: # This is for modules, not classes
passMethod and Function Naming
Methods represent actions. They should start with a verb and clearly describe what they do. Java uses camelCase, while Python uses snake_case.
// Java - camelCase, starts with a verb
public User findUserById(Long id) { }
public void sendWelcomeEmail(User user) { }
public boolean isEligibleForDiscount(Order order) { }
// Bad
public User user(Long id) { } // no verb
public void process(Object o) { } // too vague# Python - snake_case, starts with a verb
def find_user_by_id(user_id: int) -> User:
pass
def send_welcome_email(user: User) -> None:
pass
# Bad
def data(x): # no verb, unclear parameter
passVariable Naming
Variables should describe the data they hold. Use meaningful names and avoid single-letter variables (except in trivial loops). Never abbreviate unless the abbreviation is universally understood (e.g., url, id, http).
// Java - Good: descriptive, self-documenting
String customerEmail = "john@example.com";
int maxRetryAttempts = 3;
List<Order> pendingOrders = orderService.findPending();
// Bad: cryptic, abbreviated, meaningless
String ce = "john@example.com";
int x = 3;
List<Order> list1 = orderService.findPending();# Python - Good
customer_email = "john@example.com"
max_retry_attempts = 3
pending_orders = order_service.find_pending()
# Bad
ce = "john@example.com"
x = 3
list1 = order_service.find_pending()Constants
Constants use UPPER_SNAKE_CASE in both Java and Python. This convention immediately signals to the reader that the value should never change.
// Java
public static final int MAX_LOGIN_ATTEMPTS = 5;
public static final String DEFAULT_TIMEZONE = "UTC";
public static final double TAX_RATE = 0.08;# Python
MAX_LOGIN_ATTEMPTS = 5
DEFAULT_TIMEZONE = "UTC"
TAX_RATE = 0.08Package and Module Naming
Packages and modules organize your code into logical groups. Keep them lowercase and concise.
// Java packages - all lowercase, dot-separated, reverse domain
package com.company.userservice.repository;
package com.company.payment.gateway;
// Bad
package com.company.UserService; // no PascalCase in packages# Python modules - all lowercase, underscores if needed
import user_service
import payment_gateway
from data_processing import clean_data
# Bad
import UserService # PascalCase is for classes, not modules
import data-processing # hyphens are invalid in module namesBoolean Naming
Booleans answer yes/no questions. Prefix them with is, has, can, should, or was to make conditions read like natural English.
// Java - reads naturally in if-statements
boolean isActive = true;
boolean hasPermission = user.checkAccess(resource);
boolean canRetry = attempts < MAX_LOGIN_ATTEMPTS;
boolean shouldNotify = preference.isEmailEnabled();
// Bad - forces the reader to guess the type
boolean active = true; // could be a String
boolean flag = true; // meaningless
boolean check = false; // check what?# Python
is_active = True
has_permission = user.check_access(resource)
can_retry = attempts < MAX_LOGIN_ATTEMPTS
should_notify = preference.is_email_enabled()
# Bad
active = True
flag = TrueCommon Anti-Patterns to Avoid
Here are the naming mistakes that show up most often in code reviews. Avoid them deliberately.
- Single-letter variables —
a,b,x,dtell you nothing. The only exception isi,j,kin short loops. - Hungarian notation —
strName,intAge,lstUsers. Modern IDEs and type systems make this redundant. Let the type system do its job. - Meaningless suffixes —
data,info,stuff,object. What data? Be specific:userDatais better,userProfileis best. - Inconsistent conventions — Mixing
getUser(),fetch_order(), andretrievePayment()in the same codebase. Pick one verb and stick with it. - Negated booleans —
isNotValidleads to confusing double negatives:if (!isNotValid). UseisValidinstead. - Overly long names —
getAllActiveUsersThatHaveNotBeenDeletedFromDatabase()is too much. Aim for clarity, not a full sentence. Something likefindActiveUsers()is better.
Quick Reference
| Element | Java | Python |
|---|---|---|
| Class | UserAccount |
UserAccount |
| Method/Function | findUserById() |
find_user_by_id() |
| Variable | customerEmail |
customer_email |
| Constant | MAX_RETRY |
MAX_RETRY |
| Package/Module | com.company.service |
user_service |
| Boolean | isActive |
is_active |
Naming is one of those skills that separates junior developers from senior ones. It costs nothing extra to choose a good name, but the clarity it provides pays dividends every time someone reads your code — including future you. Make it a habit, and your codebase will thank you.