Skip to content
Java getting started 7 min read

Data Types

Every value in Java has a type. Data types tell the compiler how much memory to allocate and what operations are legal on a value. Java is a statically typed language, which means you must declare the type of every variable before you use it.

Java splits its type system into two broad families: primitive types (built into the language, stored by value) and reference types (objects and arrays, stored as heap references).


Primitive Data Types

Java has exactly 8 primitive types. They are not objects — they are raw binary values stored directly on the stack (or inlined into an object on the heap).

TypeSizeDefaultRange / Notes
byte1 byte0−128 to 127
short2 bytes0−32,768 to 32,767
int4 bytes0−2,147,483,648 to 2,147,483,647
long8 bytes0L−9.2 × 10¹⁸ to 9.2 × 10¹⁸
float4 bytes0.0f~7 significant decimal digits (IEEE 754)
double8 bytes0.0d~15–16 significant decimal digits (IEEE 754)
char2 bytes'\u0000'0 to 65,535 (UTF-16 code unit)
booleanJVM-definedfalsetrue or false only

Note: Defaults above apply only to instance and static fields. Local variables are not given defaults — the compiler forces you to initialize them before use.

Integer Types

public class IntegerTypes {
    public static void main(String[] args) {
        byte  b  = 100;
        short s  = 30_000;       // underscore separators (Java 7+) improve readability
        int   i  = 2_000_000;
        long  l  = 9_000_000_000L; // 'L' suffix required for long literals

        System.out.println("byte:  " + b);
        System.out.println("short: " + s);
        System.out.println("int:   " + i);
        System.out.println("long:  " + l);
    }
}

Output:

byte:  100
short: 30000
int:   2000000
long:  9000000000

Tip: Prefer int as your default integer type. Use long when values might exceed ~2 billion (e.g., timestamps, large counts). Use byte or short only when memory is critical (large arrays).

Floating-Point Types

public class FloatingPoint {
    public static void main(String[] args) {
        float  f = 3.14f;          // 'f' suffix is required
        double d = 3.141592653589; // double is the default for decimal literals

        System.out.println("float:  " + f);
        System.out.println("double: " + d);

        // Beware: floating-point arithmetic is approximate
        System.out.println(0.1 + 0.2); // prints 0.30000000000000004
    }
}

Output:

float:  3.14
double: 3.141592653589
0.30000000000000004

Warning: Never use float or double for money or exact decimal arithmetic. Use java.math.BigDecimal instead.

char Type

char stores a single UTF-16 code unit. You can assign a character literal, a Unicode escape, or an integer in the range 0–65,535.

public class CharDemo {
    public static void main(String[] args) {
        char letter  = 'A';
        char unicode = 'A'; // same as 'A'
        char digit   = 65;       // also 'A' — chars are unsigned 16-bit integers

        System.out.println(letter);   // A
        System.out.println(unicode);  // A
        System.out.println(digit);    // A
        System.out.println((int) letter); // 65 — cast to see numeric value
    }
}

Output:

A
A
A
65

See the Unicode System page for a deeper look at how Java handles character encoding.

boolean Type

public class BooleanDemo {
    public static void main(String[] args) {
        boolean isJavaFun   = true;
        boolean isHardToLearn = false;

        System.out.println("Java is fun: "          + isJavaFun);
        System.out.println("Java is hard to learn: " + isHardToLearn);
    }
}

Output:

Java is fun: true
Java is hard to learn: false

Note: In Java, boolean is not numeric. You cannot write if (1) — only if (someBoolean).


Reference Data Types

Reference types include classes, interfaces, arrays, and enums. A variable of reference type holds a reference (pointer) to an object on the heap, not the object itself.

public class ReferenceDemo {
    public static void main(String[] args) {
        String name = "DevCraftly";   // String is a class (reference type)
        int[]  nums = {1, 2, 3};      // array is also a reference type

        System.out.println(name);
        System.out.println(nums[0]);

        String copy = name;           // both variables point to the same object
        System.out.println(copy == name); // true — same reference
    }
}

Output:

DevCraftly
1
true

Tip: The default value for any reference variable is null (field or array element). Accessing a member through a null reference throws a NullPointerException.


Type Casting

Sometimes you need to convert between types. Java supports two kinds of casting.

Widening (Implicit) Casting

Moving to a larger type is automatic and safe — no data is lost.

byte → short → int → long → float → double
int  i = 42;
long l = i;      // automatic widening
double d = l;    // automatic widening again
System.out.println(d); // 42.0

Narrowing (Explicit) Casting

Moving to a smaller type requires an explicit cast — you may lose information.

double pi    = 3.14159;
int    rough = (int) pi;   // truncates decimal portion
System.out.println(rough); // 3

Warning: Narrowing casts silently truncate or wrap values. (byte) 130 gives -126 because 130 overflows a signed byte.


Literals

A literal is a fixed value written directly in source code.

int    hex  = 0xFF;          // hexadecimal
int    bin  = 0b1010_1010;   // binary (Java 7+)
long   big  = 100_000_000L;
float  f    = 1.5f;
double d    = 1.5;           // double by default
char   c    = '\n';          // escape sequence — newline
String s    = "hello";       // String literal

Wrapper Classes

Every primitive type has a corresponding wrapper class in java.lang:

PrimitiveWrapper
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

Wrappers are needed when you work with collections (which store objects, not primitives) and provide useful utility methods:

int max = Integer.MAX_VALUE;   // 2147483647
int parsed = Integer.parseInt("42");
String s = Integer.toBinaryString(255); // "11111111"
System.out.println(max + " | " + parsed + " | " + s);

Output:

2147483647 | 42 | 11111111

Java automatically converts between primitives and their wrappers via autoboxing and unboxing. See Autoboxing & Unboxing for the full story.


Under the Hood

How Primitives Are Stored

When a primitive is a local variable, the JVM stores it on the operand stack or in a local variable slot of the current stack frame — no heap allocation happens. This is why primitives are fast.

When a primitive is an instance field, it is stored inline inside the object’s heap allocation. For example, an object with three int fields occupies roughly 12 bytes (object header) + 3 × 4 bytes = 24 bytes (aligned to 8 bytes).

Wrapper Objects and the Integer Cache

When you autobox an int between −128 and 127, Java reuses cached Integer objects rather than allocating new ones:

Integer a = 127;
Integer b = 127;
System.out.println(a == b);  // true  — same cached object

Integer c = 128;
Integer d = 128;
System.out.println(c == d);  // false — different objects

This is a classic Java gotcha. Always compare Integer objects with .equals(), not ==.

float and double: IEEE 754

Both floating-point types follow the IEEE 754 standard. A double uses 1 sign bit, 11 exponent bits, and 52 mantissa bits. Because many decimal fractions (like 0.1) cannot be represented exactly in binary, rounding errors accumulate. This is expected behavior, not a bug.

boolean Size

The Java specification does not mandate a specific byte size for boolean. In practice, the JVM typically stores a boolean field as a 4-byte int (or 1 byte in arrays), since the x86 instruction set doesn’t natively operate on single bits efficiently.


Quick Reference: Choosing the Right Type

SituationRecommended type
Whole numbers (general use)int
Very large whole numberslong
Decimal numbers (general use)double
Memory-critical large arrays of small integersbyte or short
Exact decimal arithmetic (money)java.math.BigDecimal
True/false flagsboolean
Single character / Unicode code unitchar
TextString (reference type)

Last updated June 13, 2026
Was this helpful?