JavaPrimitive Data Types

Primitive Data Types

Every variable in Java has a type, and Java splits types into two families: primitive types and reference (non-primitive) types. This page covers the primitives — the small set of built-in types that Java treats as first-class citizens of the language, not as objects.

The 8 Primitive Types

Java defines exactly eight primitive types. Each has a fixed size in memory that does not change from machine to machine, which is one of the reasons Java code behaves the same way on every platform.

Type

Size

Range / Values

Default

Example

byte

8 bits

-128 to 127

0

byte b = 100;

short

16 bits

-32,768 to 32,767

0

short s = 20000;

int

32 bits

-2,147,483,648 to 2,147,483,647

0

int i = 42;

long

64 bits

~-9.2 x 10^18 to 9.2 x 10^18

0L

long l = 42L;

float

32 bits

~6-7 significant decimal digits

0.0f

float f = 3.14f;

double

64 bits

~15 significant decimal digits

0.0

double d = 3.14159;

char

16 bits

0 to 65,535 (single Unicode character)

'\u0000'

char c = 'A';

boolean

1 bit (JVM-dependent)

true or false

false

boolean flag = true;

Tip
In practice, int is the default choice for whole numbers and double is the default choice for decimal numbers, unless you have a specific reason (memory constraints, interop, precision requirements) to pick something else.

Declaring primitives

Java
public class PrimitiveDemo {
    public static void main(String[] args) {
        byte age = 30;
        short year = 2026;
        int population = 8_000_000;
        long distanceToSun = 149_600_000_000L;
        float price = 19.99f;
        double pi = 3.14159265358979;
        char grade = 'A';
        boolean isJavaFun = true;

        System.out.println(age);
        System.out.println(year);
        System.out.println(population);
        System.out.println(distanceToSun);
        System.out.println(price);
        System.out.println(pi);
        System.out.println(grade);
        System.out.println(isJavaFun);
    }
}
30
2026
8000000
149600000000
19.99
3.14159265358979
A
true
Note
Notice the trailing L on the long literal and f on the float literal. Without the L, a number like 149_600_000_000 is too large to fit in the default int-sized literal and the code will not compile. Without the f, a decimal literal is treated as a double, which cannot be assigned to a float without an explicit cast.
Primitives Are Not Objects

This is the single most important thing to understand about primitives. A primitive variable holds its actual value directly in the memory location associated with that variable. There is no object, no header, no reference — just the raw bits of the value itself.

This is fundamentally different from reference types (String, arrays, and every class you write), where a variable holds a reference — an address that points to an object living elsewhere in memory. We cover that behavior in detail on the Non-Primitive Data Types page, but the short version is this:

Primitive Types

Reference Types

Hold the actual value

Hold an address pointing to an object

Fixed set of 8 types

String, arrays, classes, interfaces

Cannot be null

Can be null

Assignment copies the value

Assignment copies the reference

Live on the stack (for locals)

The object lives on the heap

Assigning a primitive copies the value

Java
int a = 10;
int b = a; // b gets its own copy of the value 10

b = 20;

System.out.println("a = " + a); // a is unaffected
System.out.println("b = " + b);
a = 10
b = 20
Changing b has no effect on a because each variable owns an independent copy of the value. Compare this with reference types, where two variables can end up pointing at the same underlying object.
Default Values for Uninitialized Fields

If you declare an instance variable or a static (class-level) variable without explicitly assigning it a value, Java automatically gives it a sensible default:

Type

Default Value

byte, short, int, long

0

float, double

0.0

char

'\u0000' (the null character)

boolean

false

Default values on instance fields

Java
public class DefaultsDemo {
    int count;         // defaults to 0
    double balance;    // defaults to 0.0
    boolean isActive;  // defaults to false
    char initial;      // defaults to '\u0000'

    public static void main(String[] args) {
        DefaultsDemo obj = new DefaultsDemo();
        System.out.println(obj.count);
        System.out.println(obj.balance);
        System.out.println(obj.isActive);
        System.out.println((int) obj.initial);
    }
}
0
0.0
false
0
Note
This automatic default-value behavior applies only to instance variables and static variables — fields that belong to a class or an object. It does not apply to local variables.
Local Variables Have No Default Value

A local variable — one declared inside a method, constructor, or block — is not automatically initialized. Java requires you to assign it a value before you read it. This is a compile-time check, not a runtime one, so the compiler will refuse to build code that might read an uninitialized local variable.

This will NOT compile

Java
public class UninitializedDemo {
    public static void main(String[] args) {
        int total; // local variable, no value yet

        System.out.println(total); // compiler error!
    }
}
Warning
Compilation error: variable total might not have been initialized. Unlike instance and static fields, local variables never get a free default value — you must assign one explicitly before the variable is used.

Fixed: initialize before use

Java
public class FixedDemo {
    public static void main(String[] args) {
        int total = 0; // initialized

        total = total + 10;
        System.out.println(total);
    }
}
10
Tip
This rule is actually a safety feature. It prevents an entire class of bugs — accidentally reading garbage or leftover memory — that are common in languages that don't enforce initialization.