What are the primitive data types?

In Java, there are nine possible types a value of a variable can be – a reference to an object or one of the eight primitive types:
  • byte – A signed integer from -2^7 to 2^7-1;
  • short – A signed integer from -2^15 to 2^15-1;
  • int – A signed integer from -2^31 to 2^31-1;
  • long – A signed integer from -2^63 to 2^63-1;
  • float – A 32 bit IEEE 754 floating-point number;
  • double – Similar to float, but 64-bit;
  • char – A 16-bit Unicode character, from '\u0000'(0) to '\uffff'(65535);
  • boolean – Either true or false;
By default, primitive type fields take on zero values: 0, 0L, '\u0000', false.

A separate interesting topic is boxing/unboxing. Each primitive type has its corresponding reference version. Primitive values are automatically wrapped and unwrapped as needed. This can lead to significant memory allocation costs, for example when an int loop index is used as an Object variable value and is converted to Integer unnecessarily – a common interview question. Furthermore, wrapper classes contain a set of utility methods for their primitives.

The memory footprint of a primitive is a tricky question. The specification requires the size to be sufficient for all values. The exact size is determined by the JVM implementation, which may be larger. For instance, in 64-bit HotSpot, a boolean variable does not take up just 1 bit, but 8.

For a complete understanding, a detailed official tutorial on primitive types is recommended.