Class.forName(name, false, loader) loads and links a class without requesting its initialization. The three-argument form makes loader and initialization policy explicit.
Java Class.forName: inspect an allowlisted class without initializing it
Operational contract
The method maps a short trusted key to a fixed receipt implementation name, then verifies that the loaded type implements the expected interface. Using arbitrary user text as a class name could load unrelated types or increase attack surface. The false flag avoids initialization during discovery; constructing an instance or using a static member later can still initialize the class. Linkage errors can occur while loading, and loader identity determines whether a class is assignable to this service interface.
Failure case
A configuration key names the built-in warehouse codec. The service checks its type at startup without constructing it. A key that is not on the allowlist fails before any class lookup.
Java code
import java.util.Map;
import java.util.Objects;
public class ReceiptCodecTypeGate {
public interface ReceiptCodec { byte[] encode(String receipt); }
public static class WarehouseCodec implements ReceiptCodec {
public byte[] encode(String receipt) {
return receipt.getBytes(java.nio.charset.StandardCharsets.UTF_8);
}
}
private static final Map<String, String> ALLOWED = Map.of(
"warehouse", WarehouseCodec.class.getName());
public static Class<? extends ReceiptCodec> resolve(String configurationKey)
throws ClassNotFoundException {
String className = ALLOWED.get(Objects.requireNonNull(configurationKey));
if (className == null) throw new IllegalArgumentException("Unknown receipt codec key");
ClassLoader loader = ReceiptCodecTypeGate.class.getClassLoader();
return Class.forName(className, false, loader).asSubclass(ReceiptCodec.class);
}
}Performance and ownership cost
The allowlist lookup is O(1) average for a fixed small map. Class loading and linking may perform I/O and verification once per loader; class initialization is deferred, not removed. Retaining references to classes can retain their defining loader.
Common Mistakes
- Do not pass an untrusted class name directly to Class.forName.
- Do not claim false prevents later static initialization.
- Do not assume two classes with the same name but different defining loaders are interchangeable.
