Java 1: Primitives, Wrappers & Autoboxing
easy⏱ 5 mincoursejava
The 8 primitives
boolean (1 bit logical), byte (8-bit signed), short (16-bit), int (32-bit, default integer), long (64-bit, L suffix), float (32-bit IEEE 754, f suffix), double (64-bit IEEE 754), char (16-bit unsigned, UTF-16 code unit). Each has a wrapper (Integer, Long, Double, Boolean, Character, Byte, Short, Float) giving object semantics.
int x = 42; // primitive
Integer y = 42; // autoboxed to Integer.valueOf(42)
int z = y; // unboxed via intValue()
long big = 10_000_000_000L;
double d = Double.NaN;
The Integer cache gotcha
Integer.valueOf(n) caches Integer instances for -128..127 (the default IntegerCache range). Integer a = 127; Integer b = 127; a == b is true, but Integer a = 128; Integer b = 128; a == b is false — because 128 falls outside the cache and each autobox creates a fresh object. Always use .equals() for wrapper comparison.
Integer a = 127, b = 127;
System.out.println(a == b); // true (cached)
Integer c = 128, d = 128;
System.out.println(c == d); // false (fresh objects)
System.out.println(c.equals(d)); // true (correct way)
Build an Integer cache simulator
Write an IntegerBox class that mirrors Java's caching: IntegerBox.valueOf(n) returns the same instance for -128..127 and a new instance otherwise. Verify with === (TS reference equality = Java ==) across the boundary. Also log an overflow demo: 2_147_483_647 + 1 in 32-bit signed math wraps to -2_147_483_648.
NaN is not equal to itself
Double.NaN == Double.NaN is false — IEEE 754 says NaN is unordered. Use Double.isNaN(x) to detect it. In a HashMap<Double, ?> this means two NaN keys can coexist because hashCode uses bit equality but equals uses NaN semantics — an impressive gotcha.
Quiz: == vs .equals()
When is Integer a == Integer b reliable? Never rely on it for correctness — it's true only for cached values. Always use .equals() for wrappers. The == on primitives compares values; on references it compares identity.