// Java Fundamentals · Lesson 02
Primitive Data Types and Variables
How Java stores numbers, characters and true/false values, how to name and change them, and why 7 / 2 is 3.
BY THE END OF THIS LESSON YOU CAN
- Name Java’s eight primitive types and pick the right one for a value
- Declare, initialize and change variables, and use
finalandvar - Predict integer division, overflow and rounding errors
- Convert between types, and know when you need a cast
- Tell where in the code a variable can be used
MEMORY
type · name · valuePart 1 of 6
Variables
A variable is a named place in memory that holds one value. In Java every variable has a type, and the type never changes.
// 1.1
A variable is a labelled box
When you declare a variable, Java reserves memory for one value of one type and gives it a name. Click any part of the line.
int age = 25;
In memory: a box named age, big enough for one int, holding 25.
Start with =. It does not mean what it means in math.
int age; // declare: no value yet age = 25; // assign a value int year = 2026; // both in one line
// 1.2
Declare, assign, change
A variable holds one value at a time. Assigning a new value replaces the old one. Step through the code like a debugger and watch the memory.
(output appears here)
Memory
// 1.3
Naming variables
Some names don’t compile at all. Others compile but break the conventions every Java team follows. Test yourself, then read the rules.
Does this name compile?
The rules
- Start with a letterThen any letters, digits,
_or$. - No spaces, symbols or keywordsNo
-,+or#, and no reserved words likeint,classornew. - Case-sensitive
age,AgeandAGEare three different names. - camelCase, and say what it holds
studentCount, notscorx. Booleans read like a question:isActive,hasDiscount.
Part 2 of 6
The eight primitive types
Java has eight built-in types for simple values. Everything else, including String, is built from classes.
// 2.1
Primitive types and reference types
Every type in Java is one of two kinds. The difference is what the variable actually holds.
Primitive types
The variable holds the value itself.
- Exactly eight, all lowercase:
byteshortintlongfloatdoublecharboolean - Same size on every computer: an
intis always 32 bits - Always a value, never
null
Reference types
The variable holds a reference: where an object lives in memory.
- Classes:
String,Scanner,LocalDate, and every class you write - Names start with a capital letter
- Can be
null, meaning “points to nothing”
Stack · main method
Heap · objects
Remember the stack and the heap from lesson 1? Primitive values sit right inside the method’s stack frame. Objects live on the heap, and the variable only holds a reference to them.
String is a class, not a primitive, but Java treats it specially: you can write "text" literals and join strings with +. Lesson 7 covers strings. Every primitive also has a class partner, called a wrapper: int → Integer, double → Double, char → Character. You will need them later for collections.
// 2.2
Meet the eight
Four for whole numbers, two for decimals, one for characters, one for true/false. The bars show how much memory each one uses. Click a type.
In practice you need two: int for whole numbers and double for decimals. Reach for the others only when you have a reason, like long for numbers past 2.1 billion.
// 2.3
Writing values: literals
A literal is a value written directly in the code. How you write it decides its type.
| Literal | Type | What it means |
|---|---|---|
42 | int | Every whole number is an int by default |
42L | long | L makes it a long. Use a capital L: a small l looks like 1 |
3.14 | double | Every number with a decimal point is a double by default |
3.14f | float | f makes it a float |
1_000_000 | int | Underscores make big numbers readable. Java ignores them |
1.5e3 | double | Scientific notation: 1.5 × 10³ = 1500.0 |
0xFF · 0b1010 | int | Hexadecimal (255) and binary (10) |
'A' | char | Single quotes, exactly one character |
'\n' · '\t' | char | Escape sequences: new line, tab. Also '\'' and '\\' |
'\u0041' | char | A Unicode code, here 'A' |
true | boolean | Or false. Always lowercase |
"A" | String | Double quotes mean String, even for one character |
010 | int | Trap: a leading zero means octal. This is 8, not 10 |
// 2.4
Pick the right type
Real data, real choices. Pick a type for each value.
Part 3 of 6
How numbers behave
Integer division, overflow and rounding errors: three surprises behind many real bugs.
// 3.1
Why 7 / 2 is 3
The type of the result depends on the types of the numbers. Try it in the practice JShell: type a calculation and press Enter, or click a suggestion.
- int with int gives an intThe decimal part is dropped, not rounded:
7 / 2is3, and-7 / 2is-3. - One double makes it a double
7.0 / 2and7 / 2.0are both3.5. %gives the remainder7 % 2is1. Handy for checking even and odd numbers.- Dividing by zeroWith ints the program crashes. With doubles you get
InfinityorNaN.
TRY THESE
// 3.2
Overflow: when numbers wrap around
Each integer type has a fixed number of bits. Go past the biggest value and it wraps around to the smallest, with no error and no warning. Here is a byte: 8 bits. Click the bits, or count with +1.
The leftmost bit counts as −128 instead of +128. That is how Java stores negative numbers (it’s called two’s complement). An int works the same way with 32 bits.
int max = Integer.MAX_VALUE; // 2147483647 System.out.println(max + 1); // -2147483648 // Want an error instead of a silent wrap? Math.addExact(max, 1); // ArithmeticException: integer overflow
// YouTube, 2014
“Gangnam Style” broke the counter
The video passed 2,147,483,647 views, the largest value of a 32-bit int. YouTube had to switch its view counter to a 64-bit integer.
// Boeing 787, 2015
Restart every 248 days
A counter in the plane’s generator control units counted hundredths of a second. After 2³¹ of them, about 248 days, it would overflow and shut down the electrical power. Airlines had to restart the planes regularly until a fix shipped.
// 3.3
Why 0.1 + 0.2 is not 0.3
A double stores numbers in binary. Most decimal fractions, like 0.1, have no exact binary form, the same way 1/3 has no exact decimal form (0.333…). Tiny rounding errors appear and add up.
System.out.println(0.1 + 0.2); System.out.println(1.1 * 3); System.out.println(0.1 + 0.2 == 0.3);
$ java Main
0.30000000000000004
3.3000000000000003
false
Add 0.1, ten times
Fine for measurements
Temperatures, distances, averages, percentages. An error in the 17th digit doesn’t matter, and double is fast.
Never for money
Lose a tiny fraction of a qəpik on each of millions of payments and the totals stop matching. Banks count money exactly: as a whole number of qəpik in a long, or with BigDecimal, a class for exact decimal math.
long priceInQepik = 1249; // 12.49 AZN
Part 4 of 6
Converting between types
Sometimes Java converts a value for you. Sometimes you must ask with a cast, and accept that data may be lost.
// 4.1
Widening and narrowing
From a smaller type to a bigger one, Java converts automatically: that’s widening. From bigger to smaller you must write a cast, like (int): that’s narrowing, and it can lose data.
and char → int. Following the arrows is automatic, even several steps: byte → double works too.
From
To
// 4.2
Casting: predict the result
A cast is a type in brackets in front of a value. Before you click, predict what JShell prints.
Want to round instead of cut off? Math.round(3.99) gives 4.
Part 5 of 6
Variables in your program
Constants, letting Java pick the type, and where in the code each variable can be used.
// 5.1
final and var
Two keywords you put in front of a variable: one locks the value, the other lets the compiler work out the type.
final: set once, never changed
Name constants in UPPER_SNAKE_CASE. They replace “magic numbers”: price * VAT_RATE says what 0.18 means.
$ javac Main.java Main.java:9: error: cannot assign a value to final variable VAT_RATE VAT_RATE = 0.20; ^ 1 error
var: Java picks the type
Since Java 10, a local variable can use var instead of a type. The compiler reads the value and fixes the type. Which type does each line get?
- The type is still fixed. After
var count = 10;,count = "ten";fails: String cannot be converted to int. - It needs a value.
var total;doesn’t compile. - Only for local variables inside methods.
While you are learning, write the types out. It trains you to think about them. Use var later, when the type is obvious from the right side.
// 5.2
Scope: where a variable lives
A variable exists from the line where it is declared to the } that closes its block. Outside that block, Java doesn’t know it. Pick a variable to see its scope.
Rules of scope
- Inner blocks can see variables from outer blocks. Outer code can’t see inside.
- Two separate blocks can each have their own variable with the same name.
- Inside one method, a name can’t be declared twice, even in an inner block.
- Keep scope small: declare a variable right before you need it.
if runs its block only when the condition is true. You will learn it properly in lesson 4.
// 5.3
Break it on purpose
The type checks in this lesson happen at compile time, so javac catches them before anything runs. Pick a mistake to see the real error message and how to fix it.
Part 6 of 6
Wrap-up
What to remember, a quiz to check yourself, and your homework.
// 6.1
Key takeaways
A variable has a type, a name and a value. The value can change; the type never does.
finallocks the value too.Java has eight primitive types. Use
intfor whole numbers anddoublefor decimals unless you have a reason not to.Whole-number literals are
intand decimals aredouble. AddLfor long andffor float.int / intdrops the decimal part, and integers wrap around silently when they overflow.doublehas small rounding errors. Never use it for money.Widening is automatic. Narrowing needs a cast and can lose data. A local variable needs a value before use, and lives only inside its block.
// 6.2
Check yourself
Ten questions. You see the answer right after you pick.
// 6.3
Homework
Tick items as you finish them. Your ticks are saved in this browser only.
// 6.4
Questions?
Next lesson: Operators and Expressions. Arithmetic, comparison, logical and bitwise operators, and why x++ and ++x are not the same.
int a = 10, b = 3; System.out.println(a % b); // 1 System.out.println(a > b && b > 0); // true int x = 5; System.out.println(x++ + ++x); // ?