Skip to content
  • Java Best Practices · Java

Java Best Practices

LearnViaNotes @learnvianotes· 4 min read

The habits that separate working Java from good Java — mostly from Joshua Bloch's Effective Java.

Naming conventions

ElementConventionExample
Class, interface, record, enumPascalCase, nounsOrderService, Comparable
MethodcamelCase, verbscalculateTotal(), isEmpty()
Variable / parametercamelCaseitemCount
Constant (static final)UPPER_SNAKE_CASEMAX_RETRIES
Packagelowercase, reversed domaincom.example.billing
Type parametersingle capital letterT, E, K, V, R
Enum constantUPPER_SNAKE_CASEStatus.IN_PROGRESS

Effective Java highlights

Composition over inheritance — the classic bug

Subclassing HashSet to count insertions double-counts, because HashSet.addAll internally calls the overridden add. You depended on an implementation detail of the superclass.

Java
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

public class Main {
    static class CountingSet<E> extends HashSet<E> {
        int added = 0;

        @Override public boolean add(E e) { added++; return super.add(e); }

        @Override public boolean addAll(Collection<? extends E> c) {
            added += c.size();
            return super.addAll(c);        // calls our add() again for every element!
        }
    }

    public static void main(String[] args) {
        CountingSet<String> s = new CountingSet<>();
        s.addAll(List.of("a", "b", "c"));
        System.out.println(s.added);       // expected 3
    }
}
Output
6

equals without hashCode

Java
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class Main {
    static final class Bad {
        final int id;
        Bad(int id) { this.id = id; }
        @Override public boolean equals(Object o) { return o instanceof Bad b && b.id == id; }
        // hashCode NOT overridden → identity hash codes differ
    }

    static final class Good {
        final int id;
        Good(int id) { this.id = id; }
        @Override public boolean equals(Object o) { return o instanceof Good g && g.id == id; }
        @Override public int hashCode() { return Objects.hash(id); }
    }

    public static void main(String[] args) {
        Set<Bad> bad = new HashSet<>();
        bad.add(new Bad(1));
        System.out.println(bad.contains(new Bad(1)));

        Set<Good> good = new HashSet<>();
        good.add(new Good(1));
        System.out.println(good.contains(new Good(1)));
    }
}
Output
false
true

Return empty, not null

Java
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class Main {
    static final Map<String, List<String>> ORDERS = Map.of("asha", List.of("book", "pen"));

    static List<String> ordersOf(String user) {
        return ORDERS.getOrDefault(user, List.of());     // never null
    }

    static Optional<String> firstOrder(String user) {
        return ordersOf(user).stream().findFirst();
    }

    public static void main(String[] args) {
        for (String item : ordersOf("ravi")) System.out.println(item);   // simply loops 0 times
        System.out.println(ordersOf("ravi").size());
        System.out.println(firstOrder("asha").orElse("none"));
        System.out.println(firstOrder("ravi").orElse("none"));
    }
}
Output
0
book
none

Code hygiene checklist

Instead of…Prefer…
new Integer(5) (deprecated)Integer.valueOf(5) or autoboxing
Vector, Hashtable, StackArrayList, HashMap / ConcurrentHashMap, ArrayDeque
Date, Calendar, SimpleDateFormatLocalDate, Instant, DateTimeFormatter
int status codesan enum
Manual close() in finallytry-with-resources
if (x != null) x.foo() chainsOptional for return values, or Objects.requireNonNullElse

Why prefer composition over inheritance?

Why return an empty collection instead of null?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report