Java has primitive types (raw values) and reference types (objects).
The eight primitives
| Type | Size | Range | Example |
|---|---|---|---|
byte |
8-bit | −128 … 127 | byte b = 100; |
short |
16-bit | −32,768 … 32,767 | short s = 5000; |
int |
32-bit | ±2.1 billion | int i = 100000; |
long |
64-bit | very large | long l = 15000000000L; |
float |
32-bit | ~7 digits | float f = 5.75f; |
double |
64-bit | ~15 digits | double d = 19.99; |
boolean |
— | true / false |
boolean ok = true; |
char |
16-bit | one character | char c = 'A'; |
Note the suffixes: L for long, f for float. Without them, 15000000000
is an int (overflow) and 5.75 is a double (type error).
Defaults: use int for whole numbers and double for decimals unless
you have a reason not to.
Reference types
Everything else — String, arrays, and every class — is a reference
type. Its default value is null.
String name = "Sita";
int[] marks = {88, 74, 91};
Scanner sc = new Scanner(System.in);Type casting
Widening (small → large) happens automatically:
int i = 100;
long l = i; // fine
double d = l; // fineNarrowing (large → small) must be explicit and can lose data:
double d = 9.78;
int i = (int) d; // 9 — the decimal part is discarded, not roundedInteger division
A classic bug: dividing two ints gives an int.
System.out.println(5 / 2); // 2 ← not 2.5
System.out.println(5 / 2.0); // 2.5
System.out.println((double) 5 / 2); // 2.5Wrapper classes
Each primitive has an object counterpart, needed when a class requires an object (collections, generics):
int → Integer, double → Double, char → Character,
boolean → Boolean, and so on.
Integer boxed = 42; // autoboxing
int unboxed = boxed; // auto-unboxing
int parsed = Integer.parseInt("123");
double d = Double.parseDouble("3.14");
String s = String.valueOf(42);Beware: an Integer can be null, and unboxing a null throws a
NullPointerException.