Menu

Java Data Types: Primitives, Reference Types, and Defaults

Java's data types explained - the eight primitive types, reference types, default values, literals and suffixes, overflow, and when to use which numeric type.

This page includes runnable editors - edit, run, and see output instantly.

Two Families: Primitives and References

Every value in Java has a type, and that type falls into one of two families. Primitive types hold a raw value directly - a number, a single character, or a true/false. Reference types hold a reference (a pointer) to an object living elsewhere in memory: String, arrays, and every class you or the libraries define.

The distinction matters because primitives are lightweight and copied by value, while reference variables point at shared objects. Start with the eight primitives - they are the foundation everything else is built on.

The Eight Primitive Types

Java has exactly eight built-in primitive types. Six are numbers, one is a character, one is a boolean:

A few things to notice up front: the underscores in 2_000_000 are just visual separators the compiler ignores, the L and f suffixes are required (more on that below), and char uses single quotes while a String would use double quotes.

Choosing a Numeric Type

You almost never need byte or short - they save memory only in huge arrays. The real decisions are between int/long for whole numbers and float/double for decimals.

TypeSizeUse when
int32-bitThe default for whole numbers (up to ~2.1 billion)
long64-bitValues past ~2 billion: millisecond timestamps, file sizes
double64-bitThe default for decimals - good precision
float32-bitOnly when memory is tight and precision can suffer

The trap is overflow. An int wraps around silently when it exceeds its range - no error, just a wrong answer:

maxInt + 1 overflows to -2147483648 because both operands are int and the result stays an int. Casting one side to long first does the math in 64 bits. When a value might be large - especially milliseconds since 1970 - reach for long.

Literals and Their Suffixes

A bare number literal has a default type, and that bites people. 100 is an int; 3.14 is a double. To write a long or a float literal you must add a suffix:

Drop the L from 8_000_000_000L and the code will not compile, because the literal exceeds the int range before it ever reaches the long variable. Drop the f from 0.5f and Java complains that a double cannot be assigned to a float without a cast. The suffix is case-insensitive, but use uppercase L - a lowercase l looks exactly like the digit 1.

char Is a Number in Disguise

A char stores a 16-bit Unicode code unit, which means it doubles as a small unsigned integer. You can do arithmetic on it and convert back and forth with a cast:

This is occasionally handy for shifting letters, but do not lean on it for text - that is what String is for. Note char uses single quotes ('A'); double quotes ("A") make a one-character String, which is a completely different type.

Default Values (and the Local-Variable Gotcha)

Fields and array elements that you do not initialize get a sensible default. But this only applies to fields and array slots - local variables get no default, and using one before assigning a value is a compile error, not a runtime surprise.

If you instead wrote int x; System.out.println(x); inside main, the compiler would reject it with "variable x might not have been initialized." That strictness is a feature - it stops you from reading garbage. The defaults to remember: numeric types 0, boolean false, char '�', and every reference type null.

Next: Strings

String is the reference type you will touch most - text, joined values, user input. It behaves differently from the primitives here: it is an object, it is immutable, and comparing strings has its own pitfalls. The next page covers it.

Frequently Asked Questions

How many data types are there in Java?

Java has eight primitive types: byte, short, int, long, float, double, char, and boolean. Everything else - String, arrays, and any object - is a reference type. So the count of built-in primitives is fixed at eight, while reference types are unlimited because you (and the libraries) define new classes.

What is the difference between int and long in Java?

Both hold whole numbers, but int is 32-bit (range about ±2.1 billion) and long is 64-bit (range about ±9.2 quintillion). Use int by default; switch to long when a value can exceed two billion - timestamps in milliseconds, file sizes, large counters. A long literal needs an L suffix, e.g. long big = 10000000000L;.

What is the default value of an int in Java?

An int field defaults to 0 - but only fields and array elements get defaults. A long defaults to 0L, double to 0.0, boolean to false, char to '\u0000', and any reference type to null. Local variables get no default at all - you must assign one before use or the code will not compile.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED