A program is read far more often than it is written. You read it while you debug it, a partner reads it when you split the work, and you read it again three months later when a new feature is needed — by which point you remember almost nothing about why you wrote it that way. Maintenance, the work of fixing and extending software that already runs, is the longest stage of the life cycle, and its cost depends almost entirely on how readable the code is. Java programmers share a set of conventions for exactly this reason. None of them changes what the program does; the compiler ignores names, spacing and comments. They exist so that a person can understand the code quickly and change it without breaking something else.
Naming and layout conventions
| Kind of name | Convention | Good examples | Avoid |
|---|---|---|---|
| Class | UpperCamelCase noun, matching the file name | CheckoutTotal, StudentRecord | checkout, s, Program1 |
| Method | lowerCamelCase, starting with a verb | sumPrices, applyDiscount, printReport | Sum, doStuff, method2 |
| Variable | lowerCamelCase noun saying what it holds | subtotal, passCount, studentName | t, x2, temp3, data |
| Boolean | Reads as a yes/no question | isValid, hasPaid, found | flag, check |
| Constant | UPPER_SNAKE_CASE, declared final | HST_RATE, MAX_STUDENTS | hstrate, Rate |
Layout matters for the same reason. Indent one level, usually four spaces, for every block inside braces, so the shape of the code on screen matches its logic: you can see at a glance which statements are inside the loop and which are inside the if. Put one statement per line, leave spaces around operators (total = total + price;, not total=total+price;), and use blank lines to separate the steps of a method the way paragraphs separate ideas. Choose a brace style and use it everywhere. Most editors will re-indent a file automatically, so there is no excuse for misleading indentation — and misleading indentation is dangerous, because a line indented as though it were inside an if will still run every time if it is outside the braces.
Constants and comments
A magic number is a literal value buried in code with no explanation, such as 0.13 or 35 in the middle of a calculation. It causes two problems. The reader has to guess what it means, and when the value changes — a tax rate, a class size, a passing mark — you must hunt down every copy and hope you neither miss one nor change an unrelated 0.13 by mistake. A named constant fixes both: declare it once with final, so the compiler refuses any attempt to reassign it, give it a name that explains it, and use the name everywhere. Values like 0, 1 and 100 in a percentage are usually fine as they are; the test is whether a reader would ask "why that number?". Comments follow a similar rule. The code already says WHAT it does, so a comment should say WHY, or explain something the code cannot. Every file should open with a header comment, and every method other than main should have a Javadoc comment, which starts with /** and uses tags such as @param and @return so tools can turn it into documentation.
/*
* CheckoutTotal.java
* Calculates what a customer owes for a cart of items: a volume
* discount is applied first, then Ontario HST.
* Author: J. Singh Last changed: 2026-10-01
*/
public class CheckoutTotal {
static final double DISCOUNT_THRESHOLD = 35.00; // dollars, before tax
static final double DISCOUNT_RATE = 0.10;
static final double HST_RATE = 0.13;
/**
* Takes the volume discount off a subtotal that reaches the threshold.
* @param subtotal the pre-tax total, in dollars
* @return the subtotal after any discount
*/
public static double applyDiscount(double subtotal) {
if (subtotal >= DISCOUNT_THRESHOLD) {
return subtotal * (1 - DISCOUNT_RATE);
}
return subtotal;
}
}Refactoring a messy program step by step
public class s {
public static void main(String[] args) {
double[] a = {19.99, 5.49, 12.00, 3.75};
double t=0;
for(int i=0;i<a.length;i++){t=t+a[i];}
if(t>=35){t=t-t*0.1;}
t=t*1.13;
System.out.println("Total: "+Math.round(t*100)/100.0);
}
}- Make sure it runs and record the current output (Total: 41.93). Refactoring means changing the structure WITHOUT changing the behaviour, so you need something to compare against.
- Reformat: indent every block and space the operators. Run it again — same output.
- Rename: the class becomes
CheckoutTotal(and the fileCheckoutTotal.java),abecomesprices,tbecomessubtotalortotal. Run it again. - Replace the magic numbers 35, 0.1 and 1.13 with
DISCOUNT_THRESHOLD,DISCOUNT_RATEand1 + HST_RATE. Run it again. - Extract methods for each job:
sumPrices,applyDiscount,roundToCents. main now reads like a summary of the steps. Run it again. - Add the header comment and Javadoc, run the full test set one last time, then commit the working version.
public static void main(String[] args) {
double[] prices = {19.99, 5.49, 12.00, 3.75};
double subtotal = sumPrices(prices);
double discounted = applyDiscount(subtotal);
double total = discounted * (1 + HST_RATE);
System.out.println("Total: " + roundToCents(total)); // still Total: 41.93
}Version-control habits for maintenance
- Commit small and often, and only when the program compiles and passes its tests, so every saved version is one you could safely return to.
- Write commit messages that say what changed and why: "Apply discount before tax, not after" beats "fixed stuff".
- Use a branch for an experiment or a risky change, and merge it only once it works. The main version stays runnable throughout.
- Before starting work, pull the latest version; when a bug appears, compare the current code with the last version that worked (a diff) to find the change responsible.
- Never commit passwords, keys or large generated files, and keep refactoring commits separate from feature commits so each one is easy to review.