Java has eight primitive data types: byte, short, int, long, float, double, char and boolean. Each stores a particular kind of value rather than a reference to an object. Choosing a type affects the accepted range, available operations and interpretation of the data.
Begin with int for ordinary whole-number calculations, double for approximate fractional measurements and boolean for true-or-false decisions. Learn their limits before relying on a result: a program can compile successfully while integer overflow or floating-point rounding produces an unexpected value.
Whole-number types and their ranges
byte, short, int and long are signed integer types. They use eight, sixteen, thirty-two and sixty-four bits respectively. A byte ranges from -128 through 127; short ranges from -32768 through 32767. An int ranges from -2147483648 through 2147483647, while long covers a much wider signed range. Use int for many counters and indexes, and long when the expected totals can exceed the int limit.
An integer literal normally has type int. Add L for a long literal when needed, preferably uppercase so it cannot be confused with the digit one. Smaller storage types are useful for specific data formats and arrays, but arithmetic on byte and short operands normally promotes them to int.
Overflow and integer division
An int cannot store an arbitrarily large result. Ordinary integer arithmetic wraps when its result exceeds the type’s range; it does not automatically switch to long or throw an exception. If you need a wider multiplication, make an operand long before multiplying. Assigning an already-overflowed int result to a long variable does not repair it.
Integer division discards the fractional part toward zero. With two positive integer operands, 7 / 2 produces 3 rather than 3.5. Use a floating-point operand when a fractional quotient is required. Division by zero with integer operands throws ArithmeticException. The Math.addExact and related methods can detect overflow when failure is preferable to a silently wrapped result. Choose the policy that matches the task.
float and double are approximate
float uses thirty-two bits and double uses sixty-four bits for floating-point representation. These types support fractional values over a wide range, but many decimal fractions cannot be represented exactly in binary. A double literal is the default; an F suffix identifies a float literal when you intentionally need that type.
For measurements such as distance or temperature, an approximate representation is often appropriate. For exact decimal money rules, BigDecimal is usually a better tool than assuming double arithmetic is exact. Printing a floating-point number reveals one representation of its value, while formatting to two decimal places changes only what you display. Comparing computed measurements may require a tolerance chosen for the problem rather than a direct equality test between differently calculated approximations.
boolean is a logical value
The boolean type stores either true or false. It is not an integer type, and Java does not accept 1 as a substitute for true in an if condition. A comparison such as temperature > 30 produces a boolean expression, which you can assign to a boolean variable or use directly in a condition.
Use names that describe a state or decision, such as isAvailable or needsCooling. Logical operators combine booleans: && means both conditions must hold, || means at least one must hold, and ! reverses the truth value. Java does not define a portable source-level storage size for boolean. Do not teach that it always occupies one bit or one byte, because implementation and storage context affect representation.
char stores a UTF-16 code unit
A char is an unsigned sixteen-bit value commonly used for a single UTF-16 code unit. A character literal uses single quotes, such as 'A', while a string uses double quotes. A char can represent many letters and symbols, but not every Unicode character fits into one char. Some symbols require a surrogate pair and therefore occupy two char positions in a String.
This matters when counting text. String.length counts UTF-16 code units rather than user-perceived characters. Arithmetic on a char can treat its numeric code-unit value as an integer, but adding one is not a general way to advance through meaningful letters in every language. Use character and string APIs for text processing instead of assuming all writing systems follow a simple sequence.
Practice with explained solutions
Task 1. Predict double result = 9 / 4; and then change one operand to get the fractional quotient.
Solution. The original stores 2.0. Using 9 / 4.0 produces 2.25 because division becomes floating point.
Task 2. Choose types for a seat letter, a sold-out flag and a total that may reach five billion.
Solution. Use char for a suitable single code unit, boolean for the flag and long for the count; five billion exceeds int.
Java Summary
- Choose a numeric type from the required range and precision.
- Integer division truncates toward zero; floating-point operands permit a fractional quotient.
- Widen an operand before multiplication when an int intermediate could overflow.
- Continue with casting and var.
Java Examples
Each example shows the code, the output it produces and what each part does.
Whole numbers versus fractional division
Save this complete program as DivisionTypes.java. Compile with javac --release 17 DivisionTypes.java and run with java DivisionTypes.
public class DivisionTypes {
public static void main(String[] args) {
int whole = 7 / 2;
double fractional = 7 / 2.0;
System.out.println(whole);
System.out.println(fractional);
}
}3
3.5Line-by-line explanation
- Lines 1 to 8The first division has two int operands, so its result is the integer three. The second includes the double literal 2.0, so Java performs floating-point division and stores 3.5. Merely changing the destination to double while keeping 7 / 2 would store 3.0: the integer division happens before assignment. Check operand types at the operation, not just the destination type.
Widen before multiplying
Save this complete program as PopulationEstimate.java. Compile with javac --release 17 PopulationEstimate.java and run with java PopulationEstimate.
public class PopulationEstimate {
public static void main(String[] args) {
int towns = 50000;
int peoplePerTown = 50000;
long total = (long) towns * peoplePerTown;
System.out.println(total);
}
}2500000000Line-by-line explanation
- Lines 1 to 8Casting towns to long makes this multiplication use long arithmetic. The result is two and a half billion, beyond the positive int range but well within long. Without that cast, the int multiplication would overflow before any assignment to a long variable. The example uses a cast on an operand, not on the finished product, because promotion must happen before the potentially oversized operation.
Keep text and logic distinct
Save this complete program as PrimitiveLabels.java. Compile with javac --release 17 PrimitiveLabels.java and run with java PrimitiveLabels.
public class PrimitiveLabels {
public static void main(String[] args) {
char section = 'B';
boolean available = true;
byte floor = 4;
System.out.println("Section: " + section);
System.out.println("Available: " + available);
System.out.println("Floor: " + floor);
}
}Section: B
Available: true
Floor: 4Line-by-line explanation
- Lines 1 to 10section stores one code unit, available stores a logical state and floor stores a small integer. Printing them beside string labels creates readable text without changing their original types. The character literal uses single quotes because it is a char. Changing section to "B" would require a String variable. The boolean value prints its word form, but it does not become a string inside the variable.
Common Java Mistakes
Assuming a long destination prevents overflow
Do not assume that a large result becomes safe because the destination is long. Evaluate the expression’s operand types first. Likewise, do not use double as a universal replacement for every number: it trades exact integer or decimal properties for approximate floating-point behavior. For a required range, document the largest expected input and choose a calculation that remains valid at that boundary.
Java FAQ
Is String a primitive type?
No. String is a reference type, even though Java provides convenient literals and concatenation syntax for it.
Does Java automatically report overflow?
Ordinary int and long arithmetic can wrap silently. Use checked Math operations or explicit range validation when overflow must be reported.
Which number type should I use by default?
Use int for whole numbers and double for decimals unless you have a reason not to. Switch to long for values that may exceed about two billion, such as file sizes or timestamps, and use BigDecimal for money and other exact decimal amounts.
Why can a char be used like a number?
A char stores a character's UTF-16 code, so arithmetic uses that number. 'A' + 1 is the int 66, and casting back with (char) ('A' + 1) gives 'B'. This is handy for simple tasks such as shifting letters, but Character methods are clearer for checks like Character.isDigit(c).
What are the default values of primitive fields?
Fields that aren't assigned get 0 for the integer types, 0.0 for float and double, '\u0000' for char and false for boolean. Local variables inside methods get no default and must be assigned before use.
Java Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
What happens in long total = 50000 * 50000?
Which declaration represents a true-or-false state?
Java Quiz
2 questions to check what you learned.
How many primitive types does Java have?
- Eight
- Seven
- Nine
What does 7 / 2 evaluate to with int operands?
- 3
- 3.5
- 4