Skip to content
Theory · Variables and types · lesson 3 of 8

Primitive types

In the previous lesson every variable had the type int. But boxes in Java come in different shapes and sizes: for small whole numbers, for huge ones, for fractions, for a single character and for a yes-or-no answer.

Picture a warehouse with boxes of standard sizes. A small box takes less room, but a large item will not fit into it. Numbers work the same way: the type decides how much memory a variable takes and which values fit into it. Here is a program where each variable has its own type:

JAVA
public class Main {
    public static void main(String[] args) {
        int age = 30;
        long population = 8_100_000_000L;
        double price = 19.99;
        char grade = 'A';
        boolean ready = true;
        System.out.println(age);        // 30
        System.out.println(population); // 8100000000
        System.out.println(price);      // 19.99
        System.out.println(grade);      // A
        System.out.println(ready);      // true
    }
}

Five variables, five different box shapes. Java has eight such built-in types in all, and they are called primitive types: the value of such a variable sits right inside it. How many primitive types Java has, and which ones, is a common interview question. Let's go through them in groups.

Eight primitive types

Whole numbers: byte, short, int, long

The four whole-number types differ in size. The more bits a variable takes, the more numbers fit into it:

TypeSizeRange
byte8 bits-128 to 127
short16 bits-32768 to 32767
int32 bitsabout ±2.1 billion
long64 bitsabout ±9.2 × 10¹⁸

Whole numbers usually go into an int. The type long is used when a number may not fit into an int: the world's population, time in milliseconds, amounts in cents. byte and short are rare: they appear where every byte of memory counts.

Fractions: float and double

double keeps a fraction in 64 bits, with about 15–16 significant digits. float takes 32 bits and is precise to about 7 digits. Fractions in Java usually go into a double, and float is used when memory is tight.

Character: char

char holds one character: a letter, a digit or a sign. Its value is written in single quotes: 'A', '7', '?'. A char variable takes 16 bits.

Logical type: boolean

boolean holds a yes-or-no answer: true or false. It has no other values, and it is not a number: you cannot write 0 instead of false or 1 instead of true.

Literals

A value written right in the code is called a literal. The compiler tells a literal's type from how it is written:

  • 30 is an int: a whole number with no suffix;
  • 8_100_000_000L is a long: the letter L at the end;
  • 19.99 is a double: a fraction with no suffix;
  • 2.5f is a float: the letter f at the end;
  • 'A' is a char: one character in single quotes;
  • true and false are boolean.

The _ sign inside a number is there only for people: 1_000_000 reads better than 1000000, and the compiler ignores the underscores. The L suffix is written in upper case because a lower-case l is hard to tell from the digit one.

An important rule: a whole-number literal without L always has the type int, even when a long stands on the left. That is why a big number for a long is written with the suffix:

JAVA
long big = 3_000_000_000L;
System.out.println(big); // 3000000000

Remove the L, and the program does not compile. Three billion does not fit into an int, and the type long on the left does not change that:

TEXT
error: integer number too large

This is where the warehouse picture falls short. You can sometimes squeeze a slightly bigger item into a real box. The compiler does not do that: it rejects a value that does not fit the box, so byte b = 200; does not compile either.

String is not a primitive

Text in double quotes, such as "Anna", is kept in a variable of type String: String name = "Anna";. It is not a ninth primitive type but a class, which is why its name starts with a capital letter.

Do not mix up the quotes:

  • 'A' is a char, one character;
  • "A" is a String, even though it holds one character.

Common mistake

A fraction was put into a float without the suffix:

JAVA
float ratio = 2.5; // ✗
TEXT
error: incompatible types: possible lossy conversion from double to float

The program does not compile. The literal 2.5 has the type double, and going from a double to the smaller float may lose precision, so the compiler does not do it silently. You need a float literal: float ratio = 2.5f;.

Key points

  • Java has eight primitive types: byte, short, int, long, float, double, char, boolean.
  • Whole numbers usually go into an int and fractions into a double; String is a class, not a primitive type.
  • A whole-number literal without L is an int, so a big number for a long is written with the suffix: 3_000_000_000L.
  • The literal 2.5 is a double, and a float needs the f suffix: 2.5f.