Primitive data types are Java's built-in types for simple values — numbers, single characters and true/false. There are exactly eight: byte, short, int, long, float, double, char and boolean. In test automation you use them all the time: counters, timeouts, prices to verify, flags for pass/fail.
- All 8 primitive types with their exact size, range and default value
- Which type to choose for counts, money, timeouts and flags
- The difference between primitive and non-primitive (reference) types
- Five traps — overflow, integer division, 0.1 + 0.2, char arithmetic and casting — with real output
The 8 Primitive Data Types
These values were printed by Java 21 itself (program below):
| Type | Size | Range | Default value | Typical use |
|---|---|---|---|---|
byte | 8 bits | -128 to 127 | 0 | Raw bytes (files, images) |
short | 16 bits | -32,768 to 32,767 | 0 | Rarely used |
int | 32 bits | -2,147,483,648 to 2,147,483,647 | 0 | Counters, sizes, indexes — the default choice |
long | 64 bits | about ±9.2 × 1018 | 0 | Timestamps, very large counts |
float | 32 bits | about ±3.4 × 1038 (~7 digits precise) | 0.0 | Rarely needed |
double | 64 bits | about ±1.8 × 10308 (~15 digits precise) | 0.0 | Decimal numbers — the default choice |
char | 16 bits | 0 to 65,535 (a Unicode character) | '\u0000' | A single character |
boolean | — | true or false | false | Flags: isVisible, isPassed |
public class PrimitiveTypes {
static byte b; static short s; static int i; static long l;
static float f; static double d; static char c; static boolean bool;
public static void main(String[] args) {
System.out.println("byte " + Byte.SIZE + " bits " + Byte.MIN_VALUE + " to " + Byte.MAX_VALUE);
System.out.println("short " + Short.SIZE + " bits " + Short.MIN_VALUE + " to " + Short.MAX_VALUE);
System.out.println("int " + Integer.SIZE + " bits " + Integer.MIN_VALUE + " to " + Integer.MAX_VALUE);
System.out.println("long " + Long.SIZE + " bits " + Long.MIN_VALUE + " to " + Long.MAX_VALUE);
System.out.println("float " + Float.SIZE + " bits max " + Float.MAX_VALUE);
System.out.println("double " + Double.SIZE + " bits max " + Double.MAX_VALUE);
System.out.println("char " + Character.SIZE + " bits " + (int) Character.MIN_VALUE + " to " + (int) Character.MAX_VALUE);
System.out.println("Defaults: " + b + " " + s + " " + i + " " + l + " " + f + " " + d + " [" + (int) c + "] " + bool);
}
}
Output
byte 8 bits -128 to 127
short 16 bits -32768 to 32767
int 32 bits -2147483648 to 2147483647
long 64 bits -9223372036854775808 to 9223372036854775807
float 32 bits max 3.4028235E38
double 64 bits max 1.7976931348623157E308
char 16 bits 0 to 65535
Defaults: 0 0 0 0 0.0 0.0 [0] false
Note: default values only apply to fields (class variables). Local variables inside a method have no default — the compiler makes you assign them before use.
Primitive vs Non-Primitive Data Types
| Primitive | Non-primitive (reference) | |
|---|---|---|
| Examples | int, double, boolean, char | String, arrays, ArrayList, your own classes |
| Stores | The value itself | A reference (address) to an object |
| Can be null? | No | Yes |
| Has methods? | No | Yes, e.g. "abc".length() |
| Default (as a field) | 0, 0.0, false or '\u0000' | null |
Each primitive has a wrapper class — Integer, Double, Boolean… — used in collections like List<Integer>. Java converts between them automatically (autoboxing).
Non-Primitive Data Types in Java
Non-primitive (reference) data types are everything that isn't one of the 8 primitives: String, arrays, classes, interfaces, enums, records and collections such as List. A variable of these types stores a reference to an object, so it can be null and it has methods. All of them in one program (Java 21):
import java.util.ArrayList;
import java.util.List;
public class NonPrimitive {
enum Browser { CHROME, FIREFOX } // enum
record TestResult(String name, boolean passed) {} // record (Java 16+)
interface Reporter { void report(TestResult r); } // interface
static String notSet; // reference fields default to null
public static void main(String[] args) {
String title = "Login"; // String (a class)
int[] timeouts = {5, 10, 30}; // array
List<Integer> retries = new ArrayList<>(); // collection of wrapper objects
retries.add(2); // autoboxing: int -> Integer
TestResult r = new TestResult(title, true); // object of your own type
Reporter console = res -> System.out.println("Report: " + res);
System.out.println("String length: " + title.length() + ", upper: " + title.toUpperCase());
System.out.println("Array length: " + timeouts.length + ", first: " + timeouts[0]);
System.out.println("List: " + retries + ", enum: " + Browser.FIREFOX);
console.report(r);
System.out.println("Default of a reference field: " + notSet);
String a = new String("Login");
System.out.println("a == title: " + (a == title) + ", a.equals(title): " + a.equals(title));
try {
System.out.println(notSet.length());
} catch (NullPointerException e) {
System.out.println("Calling a method on null -> NullPointerException");
}
}
}
Output
String length: 5, upper: LOGIN
Array length: 3, first: 5
List: [2], enum: FIREFOX
Report: TestResult[name=Login, passed=true]
Default of a reference field: null
a == title: false, a.equals(title): true
Calling a method on null -> NullPointerException
Two rules every tester needs: compare object contents with equals(), not == (which compares references), and check for null before calling a method — otherwise you get a NullPointerException.
Five Traps Every Tester Should Know
public class Traps {
public static void main(String[] args) {
int max = Integer.MAX_VALUE;
System.out.println("1. int overflow: " + (max + 1));
long safe = (long) max + 1;
System.out.println(" with long: " + safe);
System.out.println("2. integer division 7 / 2 = " + (7 / 2) + ", 7 / 2.0 = " + (7 / 2.0));
System.out.println("3. 0.1 + 0.2 = " + (0.1 + 0.2));
char grade = 'A';
System.out.println("4. 'A' + 1 = " + (grade + 1) + ", (char)('A' + 1) = " + (char) (grade + 1));
double price = 19.99;
int rounded = (int) price;
System.out.println("5. (int) 19.99 = " + rounded + ", Math.round(19.99) = " + Math.round(price));
}
}
Output
1. int overflow: -2147483648
with long: 2147483648
2. integer division 7 / 2 = 3, 7 / 2.0 = 3.5
3. 0.1 + 0.2 = 0.30000000000000004
4. 'A' + 1 = 66, (char)('A' + 1) = B
5. (int) 19.99 = 19, Math.round(19.99) = 20
- Overflow: going past
int's maximum silently wraps to a negative number — no error. Uselongfor large totals. - Integer division drops the decimal part: 7 / 2 is 3. Make one side a
doubleto get 3.5. - Floating-point precision: 0.1 + 0.2 is not exactly 0.3. Never compare prices with
==; useBigDecimalor compare with a small tolerance. - char is a number:
'A' + 1is 66 (the Unicode value). Cast back tocharto get 'B'. - Casting truncates:
(int) 19.99is 19, not 20. UseMath.roundto round.
Common Mistakes
- Large whole numbers without
L:long big = 3000000000;fails witherror: integer number too large. Fix:3000000000L. - Decimals assigned to
floatwithoutf:float rate = 2.5;fails witherror: incompatible types: possible lossy conversion from double to float. Fix:2.5f, or simply usedouble. - Using
==to compare double values such as totals in a shopping-cart test. UseBigDecimalor a tolerance. - Thinking String is a primitive. It's a class — that's why it has methods and can be null.
Practice Exercises
- Print the result of
Integer.MAX_VALUE + 1and explain it. - Write a method that returns the average of three
intscores as adoublewithout losing the decimal part. - Verify a cart total: add 19.99 + 5.01 + 0.10 with
doubleand withBigDecimal, and compare the results.
Key Takeaways
- Java has exactly 8 primitive types; use
intanddoubleby default. - Overflow and integer division don't throw errors — they silently give wrong answers.
- Never use
doublewith==for money; useBigDecimal.
📚 Official documentation: dev.java: Primitive types · Java Language Specification: Primitive types
Frequently Asked Questions
How many primitive data types are there in Java?
Eight: byte, short, int, long, float, double, char and boolean.
Is String a primitive data type in Java?
No. String is a class (a reference type). That is why it has methods like length() and can be null.
What is the default value of int in Java?
0 — for fields. Local variables have no default value and must be assigned before use.
What is the size of char in Java?
16 bits. A char holds one UTF-16 code unit, from 0 to 65,535.
Which data type should I use for money?
Use BigDecimal. double cannot represent most decimal fractions exactly, so 0.1 + 0.2 gives 0.30000000000000004.