Data Types (Primitives & Ranges)
In the Variables lesson you met int, double, String and boolean. Now let's go deeper: Java's eight primitive types, exactly how much each one can hold, and how picking the right type prevents subtle bugs like overflow and rounding errors.
Learn Data Types (Primitives & Ranges) in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Two Families of Types
Java has exactly 8 primitive types . A primitive stores a raw value directly in a fixed block of memory — there is no object, no method, and it can never be null . They split into two families:
Each step is twice the bits, so twice the range.
double has roughly twice the precision of float.
The remaining two don't fit either family: char holds a single character, and boolean holds only true or false .
💡 Analogy: Think of types as buckets of different sizes. A byte is an egg cup, an int is a kitchen jug, and a long is a water barrel. You could carry a teaspoon of water in a barrel, but it wastes space — and you can't pour a barrel into an egg cup without spilling.
2️⃣ The Complete Range Table
Because every primitive has a fixed size, its minimum and maximum values are constants baked into the language. Memorise the int range; look the rest up via the wrapper classes ( Integer.MAX_VALUE , Long.MIN_VALUE , etc.).
Type
Size
Minimum
Maximum
Default
byte
8-bit
-128
127
0
short
16-bit
-32,768
32,767
int
32-bit
-2,147,483,648
2,147,483,647
long
64-bit
-9.2 × 10¹⁸
9.2 × 10¹⁸
0L
float
~±3.4 × 10³⁸
~7 digits
0.0f
double
~±1.8 × 10³⁰⁸
~15 digits
0.0
char
'\u0000' (0)
65,535
'\u0000'
boolean
1-bit*
false
true
* The JVM doesn't truly use a single bit; size is implementation-defined. The "Default" column is the value a field gets when you don't initialise it (local variables get no default — you must assign them).
3️⃣ Overflow — When Numbers Wrap Around
Because each type has a hard ceiling, going one past it doesn't throw an error — it silently wraps back to the minimum, like an odometer rolling over to zero.
4️⃣ char Is Secretly a Number
A char looks like a letter, but internally it's an unsigned 16-bit number — the Unicode code point . That means you can do arithmetic on characters:
This trick — treating letters as numbers — is the basis of cipher puzzles, sorting, and case-conversion. Single quotes mean char ; double quotes mean String . They are not interchangeable.
5️⃣ Choosing the Right Type
You rarely need the exotic types. Use this decision guide:
- Whole number that fits in a couple of billion → int (the default)
- Whole number bigger than ~2 billion (IDs, timestamps, byte counts) → long
- Decimal number (measurements, science, prices while learning) → double
- Yes/no flag → boolean
- A single character → char
- Real money in production → BigDecimal (a class, not a primitive)
- Raw file/network bytes → byte (often in a byte[] )
🧩 Reorder Challenge
These lines are scrambled. Put them in the correct order so the program declares a long file size, converts it to a double in megabytes, and prints it.
Why: The class and method headers must come first. bytes must be declared before it can be used, and it needs the L suffix because 5.3 billion overflows int . We divide by 1024.0 (a double) so the division is floating-point, not integer — giving 5120.00 MB .
🧠 Quick Recall
-2147483648 . Adding 1 to the largest int overflows and wraps to the smallest int.
C . 'A' is 65, plus 2 is 67, and casting 67 back to char gives 'C' .
3 then 3.5 . The first is integer division (both ints, decimal dropped); the second has a double operand, so it's floating-point division.
Common Beginner Mistakes
- ❌ Forgetting the L on big longs: long n = 3000000000; won't compile — the literal is read as an int first and overflows. Write 3000000000L .
- ❌ Forgetting the f on floats: float f = 3.14; fails because 3.14 is a double. Write 3.14f .
- ❌ Trusting double for money: 0.1 + 0.2 is 0.30000000000000004 . Use BigDecimal for currency.
- ❌ Assuming overflow errors: it doesn't throw — it wraps. Use long or Math.addExact when overflow matters.
- ❌ Single vs double quotes: 'A' is a char; "A" is a String. Mixing them is a compile error.
📋 Quick Reference
Range
Notes
-128 .. 127
Raw bytes; integer family
-32,768 .. 32,767
Rarely used
~ -2.1B .. 2.1B
Default whole number
~ -9.2 .. 9.2 × 10¹⁸
Needs L suffix: 10L
~7 decimal digits
Needs f suffix: 3.14f
~15 decimal digits
Default decimal number
0 .. 65,535
Single char in 'quotes'; a number
false / true
Only true or false
Integer.MAX_VALUE
—
int max constant
Integer.MIN_VALUE
int min constant
Long.MAX_VALUE
9,223,372,036,854,775,807
long max constant
1_000_000
1000000
Underscores aid readability
MAX + 1
wraps to MIN
Overflow is silent, not an error
BigDecimal
class
exact
Use for money, not double
Frequently Asked Questions
🎉 Lesson Complete!
You now know all 8 primitive types, their exact ranges, why long needs L and float needs f , how overflow silently wraps, and why double is wrong for money. Most of your code will use int , double , and boolean — but now you know what the others are for.
Next up: Type Casting — safely (and unsafely) converting values from one type to another.
Practice quiz
How many primitive types does Java have?
- 6
- 7
- 8
- 9
Answer: 8. Java has exactly 8 primitives: byte, short, int, long, float, double, char, boolean.
What does System.out.println(Integer.MAX_VALUE + 1); print?
- -2147483648
- 2147483648
- 0
- An error
Answer: -2147483648. Adding 1 to the largest int overflows and silently wraps around to Integer.MIN_VALUE, -2147483648.
Why does 'long big = 3000000000;' fail to compile?
- long is not a real type
- long needs quotes
- 3 billion is too small
- The literal is read as an int first and overflows
Answer: The literal is read as an int first and overflows. Whole-number literals are int by default; 3 billion overflows int. Add the L suffix: 3000000000L.
What is the value of (char)(c + 1) when char c = 'A';?
- 'A'
- 'B'
- 66
- 'a'
Answer: 'B'. 'A' is code point 65; 65 + 1 = 66, and casting back to char gives 'B'.
Which primitive is 64 bits and the default for decimal numbers?
- double
- float
- long
- int
Answer: double. double is 64-bit and the default floating-point type; float (32-bit) needs an f suffix.
What does 7 / 2.0 evaluate to?
- 3
- 4
- 3.5
- 3.0
Answer: 3.5. Because one operand is a double, it is floating-point division, giving 3.5.
What happens on integer overflow in Java?
- It throws an exception
- It silently wraps around to the minimum
- The program halts
- It returns 0
Answer: It silently wraps around to the minimum. Java does not throw on overflow — it silently wraps around, which is a real source of bugs.
What does System.out.println(0.1 + 0.2); print?
- 0.3
- 0.30
- An error
- 0.30000000000000004
Answer: 0.30000000000000004. double is binary floating point and cannot store 0.1 exactly, so the result is 0.30000000000000004.
What is the range of an int?
- -128 to 127
- about -2.1 billion to 2.1 billion
- -32,768 to 32,767
- 0 to 65,535
Answer: about -2.1 billion to 2.1 billion. int is 32-bit, ranging from -2,147,483,648 to 2,147,483,647 (about ±2.1 billion).
Why does 'float f = 3.14;' fail to compile?
- 3.14 is too large
- float cannot hold decimals
- 3.14 is a double, too wide for float
- It needs a long suffix
Answer: 3.14 is a double, too wide for float. Decimal literals are double by default; assigning a double to a float needs the f suffix: 3.14f.
Continue this course
- Previous: Variables
- Next: Type Casting