Every value in a program occupies memory, and the compiler needs to know how much space to allocate and how to interpret the bits. Without a type system, the same 32 bits could represent an integer, a floating-point number, or four characters — leading to errors, portability issues, and unpredictable behavior across platforms.
Java has eight primitive data types: byte, short, int, long, float, double, boolean, and char. Each has a fixed size and range that is platform-independent, guaranteeing the same behavior on any JVM. All other types are reference types (objects and arrays).
When a variable of a primitive type is declared, the JVM allocates exactly the specified number of bytes for it (e.g., 4 bytes for int). Primitives are stored directly on the stack (for local variables) or inline in objects (for fields). They are passed by value — a copy is made. Operations on primitives map directly to CPU instructions, making them faster than objects.
- Fixed sizes across all platforms:
intis always 32 bits,longalways 64 bits - Signed integers:
byte,short,int,longare all signed (no unsigned primitives until Java 8) - IEEE 754 floats:
floatanddoublefollow the IEEE 754 standard - char is unsigned 16-bit: Represents Unicode code units, not ASCII
- Built from: Java Platform Independence — fixed sizes across platforms are a key part of WORA
- Builds into: Java Wrapper Classes — each primitive has a corresponding wrapper type
- Builds into: Java Variables — every variable has a declared type
- Related: Java Memory Management — primitives vs objects have different memory layouts
- No unsigned primitives for
byte,short,int,longuntil Java 8 introduced unsigned API methods - char != byte: char is 16-bit Unicode, not a single byte
- Floating-point precision:
floathas ~7 decimal digits,doublehas ~15 — rounding errors are common - Division by zero: Integer types throw
ArithmeticException; floating-point returns Infinity or NaN