Skip to main content

Performance, Reflection, and Style

Source: Effective Java, 3rd Edition — Chapter 9 by Joshua Bloch (Items 63–68)

This lesson closes Chapter 9: building strings efficiently, programming to interfaces, limited reflection, native methods, optimization discipline, and Java naming conventions.

Item 63: Beware the performance of string concatenation​

+ on strings is fine for a few pieces, but repeated concatenation in a loop is O(n²) — each + copies both operands because strings are immutable.

// Bad in a loop
String result = "";
for (int i = 0; i < n; i++)
result += lineForItem(i);

// Good
StringBuilder b = new StringBuilder(n * LINE_WIDTH);
for (int i = 0; i < n; i++)
b.append(lineForItem(i));
return b.toString();

Pre-size StringBuilder when you know approximate length. For many strings, also consider joining in one pass without building one giant intermediate string per step.

Item 64: Refer to objects by their interfaces​

Declare variables, parameters, return types, and fields with the interface when one exists. Use the implementation class only in new:

Set<Son> sons = new LinkedHashSet<>();

Then switching LinkedHashSet → HashSet doesn’t break callers. Exception: code that depends on implementation-specific behavior (e.g. LinkedHashSet iteration order) must keep that type.

When no interface fits: value classes (String, BigInteger), framework base classes (OutputStream), or types with extra methods not on the interface (PriorityQueue.comparator()).

Quiz

Program to interfaces

1 / 2

Field is HashMap<K,V>; you only need Map operations and may swap to EnumMap later

Pick an answer to see if you are right.

Item 65: Prefer interfaces to reflection​

Reflection (Class.forName, Constructor.newInstance, Method.invoke) can touch classes unknown at compile time, but costs compile-time checking, readability, and speed (~11× slower for a trivial invoke in Bloch’s tests).

Limited pattern: reflect only to construct objects; use them through a known interface or superclass afterward:

Class<? extends Set<String>> cl = (Class<? extends Set<String>>) Class.forName(args[0]);
Set<String> s = cl.getDeclaredConstructor().newInstance();
s.addAll(...); // normal Set usage from here

Catch ReflectiveOperationException (Java 7+) to shrink catch blocks. If you don’t need runtime class loading, skip reflection.

Item 66: Use native methods judiciously​

JNI calls C/C++ code. Legitimate uses: platform-specific APIs, legacy native libraries, and rare extreme performance (e.g. GMP for huge BigInteger-scale math).

Downsides: no memory safety, weaker portability, harder debugging, GC can’t track native memory well, JNI transition cost. JVM and Java libraries closed most old “must go native for speed” gaps (BigInteger reimplemented in Java beat its C version).

Default: stay in Java unless a vetted native library clearly wins.

Quiz

Native methods

1 / 2

Primary reason to avoid JNI for routine hot loops today

Pick an answer to see if you are right.

Item 67: Optimize judiciously​

Don’t optimize prematurely. Write clear, well-structured programs first; profile before tuning.

  • Rule 1: Don’t do it.
  • Rule 2 (experts): Don’t do it yet — not until you have a clean baseline.
  • Rule 3: Measure before and after each change.

Think about performance at design time for hard-to-change surfaces: APIs, wire protocols, persistent formats. A mutable Dimension return from Component.getSize() forces allocations forever.

Fix algorithmic problems (quadratic string concat, wrong data structure) before micro-optimizing. Use profilers and JMH for microbenchmarks — Java’s cost model varies by JVM and hardware.

Quiz

Optimization discipline

1 / 2

statement() builds a large report with += in a loop

Pick an answer to see if you are right.

Item 68: Adhere to generally accepted naming conventions​

Typographical (JLS §6.1):

KindStyleExample
Packagelowercase, reversed domaincom.google.common.collect
Class / interfacePascalCaseHttpClient, FutureTask
Method / fieldcamelCaseremove, ensureCapacity
ConstantUPPER_SNAKEMAX_VALUE (static final immutable)
Type parametersingle letterT, E, K, V

Grammatical: classes are singular nouns (Thread); utility classes often plural (Collections); interfaces like classes or …able; action methods are verbs; boolean accessors often is/has (isEmpty); getters may be getTime or time().

Break conventions only when long-established usage says otherwise.

Quiz

Naming conventions

1 / 2

static final int maxConnections = 10;

Pick an answer to see if you are right.

Items 63–68 map​

ItemMove
63StringBuilder for many concatenations
64Set in types; LinkedHashSet in new
65Reflect to construct; interface for everything else
66JNI only when Java libraries aren’t enough
67Profile; fix algorithms; measure changes
68JLS naming — packages, classes, constants, booleans

Chapter 9 complete. Next: Exceptions (Chapter 10, Items 69–73).