library
beginnerPrimitive Types & Wrapper Classes
Know all 8 primitives, their sizes, default values, and the corresponding wrapper classes.
Eight primitives hold values directly. Each has a wrapper class that holds the same value inside an object.
Primitive = a number written on a sticky note (lightweight, no overhead). Wrapper = the same number in a sealed envelope (heavier, can be null, has methods).
Key Concepts
1
primitive bits wrapper default
------------------------------------------
byte 8 Byte 0
short 16 Short 0
int 32 Integer 0
long 64 Long 0L
float 32 Float 0.0f
double 64 Double 0.0d
char 16 Character '\u0000'
boolean - Boolean false2
The difference that matters: a wrapper can be null, a primitive cannot.
int x = null; // will not compile
Integer y = null; // fine, and dangerous3
Defaults apply to fields, not locals.
class A {
int count; // 0 automatically
void f() {
int n;
print(n); // will not compile -- locals have no default
}
}4
Small Integer values are cached, and this is the classic trap:
Integer
5
Integer a = 127, b = 127;
a == b; // true -- same cached object6
Integer c = 128, d = 128;
c == d; // false -- two objects7
The cache covers -128 to 127. So == on wrappers appears to work until a value gets large enough, and then
fails in production. Always use equals for wrappers.
==equals
8
Generics force wrappers.
List<int> nums; // will not compile
List<Integer> nums; // the only option9
Which costs memory and time: a List<Integer> of a million values is a million objects plus a million
pointers, where an int[] is one block of four megabytes.
List<Integer>int[]
10
So use the primitive streams when the volume is real:
11
IntStream.range(0, n).sum();12
Project Valhalla is the long-running effort to let value types close this gap. Worth knowing by name;
not something to depend on yet.
13
What the interviewer is probing.1. "Integer a = 127, b = 127. Is a == b true? What about 128?" Probing: the Integer cache,
which is the classic trap. Stalls: "Both true, the values are equal." Moves up: true for 127 and
false for 128 — valueOf caches -128 to 127, so == compares the same object below the boundary and
different objects above it.
14
2. "Why can a local int not be used before assignment, when a field can?" Probing: default
values. Stalls: "Both default to zero." Moves up: fields are default-initialised to zero; locals
are not, and the compiler enforces definite assignment.
15
3. "Why is List<int> illegal?" Probing: erasure and the primitive gap. Stalls: "It just is."
Moves up: generics operate on reference types because of erasure, so primitives must be boxed —
which is why the primitive streams exist.
16
4. "What does it cost to hold a million values in a List<Integer> rather than an int[]?"
Probing: whether you can quantify the overhead. Stalls: "A bit more." Moves up: a million
objects plus a million references against one contiguous block — several times the memory, and far
worse cache behaviour.