Skip to content
Study Hall
Lesson 2 of 3Programming Basics
Unit 2 · Lesson 2 of 3

Variables, Primitive Types and Casting

Declaring named storage, choosing the right type for the job, and controlling what happens when types meet — including why 5 / 2 is 2.

5 min read12 practice questionsAsk AI about this →

Key things to remember

  1. 1The eight primitives are byte, short, int, long, float, double, char, boolean. String is a class, not a primitive.
  2. 2int holds up to ; going past it wraps silently to the most negative int.
  3. 3If both operands of / are integers, Java truncates: 5 / 2 is 2. Make one side a double to get 2.5.
  4. 4% gives the remainder: 17 % 5 is 2, and n % 2 == 0 tests for even.
  5. 5Widening (byte → short → int → long → float → double) is automatic; narrowing needs a cast such as (int).
  6. 6A cast truncates toward zero — (int) 9.99 is 9 — and final constants are written in UPPER_SNAKE_CASE.

A variable is a named piece of memory that holds one value at a time. In Java you must say, up front, what kind of value it will hold, and that type can never change afterwards. Note also that = does not mean equals: it means take the value on the right and store it in the variable on the left, which is why count = count + 1 is an instruction rather than a false equation.

int score;              // declaration: reserve an int-sized box named score
score = 42;             // assignment: put 42 in it
int lives = 3;          // declaration and initialization in one line
double average = 78.5;
char grade = 'B';       // single quotes for exactly one character
boolean passed = true;
String name = "Amira";  // double quotes for text
Declaring and initializing. A variable must be given a value before it is read.
A variable is a named box in memory. Assignment puts a value in the box.int score = 0;score0score = 7;score7the 0 is gonescore = score + 3;score107 + 3, then storedint score = 0; reads as four separate ideas:int = the type (what shape of value fits) score = the name on the box= means "store into", not "is equal to" 0 = the value placed insideThe box holds one value at a time. Storing a new value destroys the old one for good.
Fig 1A variable is a labelled box in memory holding one value of one fixed type.
Eight primitives hold a raw value directly. These five cover almost everything in this course.TYPESIZERANGEEXAMPLEint32 bits−2147483648 … 2147483647int n = 42;double64 bits±1.7 × 10³⁰⁸, ~15 digitsdouble d = 3.14;boolean1 bit of meaningtrue or false onlyboolean ok = true;char16 bitsone Unicode characterchar g = 'A';long64 bits±9.2 × 10¹⁸long big = 10000000000L;String is NOT a primitive — it is an object, which is why it has a capital S.String name = "Ada"; compare it with name.equals(other), never with ==.An int literal that will not fit needs the L suffix: long big = 10000000000L;
Fig 2The eight primitives grouped by what they store and how much memory each one takes.
TypeSizeRange or purposeExample
byte8 bits−128 to 127byte b = 100;
short16 bits−32 768 to 32 767short s = 30000;
int32 bits−2 147 483 648 to 2 147 483 647int n = 250000;
long64 bitsabout ±9.2 quintillion; needs an L suffixlong big = 9000000000L;
float32 bitsdecimals, about 7 digits of precision; needs an f suffixfloat f = 2.5f;
double64 bitsdecimals, about 15 digits — Java's defaultdouble d = 2.5;
char16 bitsexactly one character, in single quoteschar c = 'A';
boolean1 bit of informationtrue or false onlyboolean ok = false;

In practice, Grade 11 work uses four of these constantly: int for counting, double for measuring, boolean for conditions, and char for a single letter or symbol. Because each type has a fixed number of bits, each also has a hard ceiling — an int tops out at , which is 2 147 483 647. Adding one more does not raise an error and does not produce a bigger number; it wraps around to −2 147 483 648 in silence. Any total that could pass about two billion belongs in a long.

String is not a primitive
String is written with a capital S because it is a class, not one of the eight primitives. A String variable holds a reference to text stored elsewhere in memory, not the text itself. That difference is harmless for now but becomes critical the moment you compare two Strings, which is why == is the wrong tool for that job.
  • Variables and methods use camelCase: totalMarks, averageSpeed, isFinished.
  • Classes use PascalCase, starting with a capital: Hello, BankAccount.
  • Constants are marked final and written in UPPER_SNAKE_CASE: final double HST_RATE = 0.13;
  • final means the compiler rejects any later attempt to reassign — it protects the value and names it at the same time.
  • Names may contain letters, digits and the underscore, but may not start with a digit and may not be a Java keyword.
  • Say what the value means. totalMarks needs no comment; tm and x need one every time.

Integer division and modulo

This is the single most common surprise in Java. When both operands of / are integers, Java performs integer division: it divides and then throws away everything after the decimal point. It does not round. So 5 / 2 is 2, 9 / 10 is 0, and -7 / 2 is −3, because truncation moves toward zero. The decimal part is not lost by accident — it was never calculated. Its partner %, the modulo operator, returns what integer division left behind, so n % 2 == 0 tests for an even number and n % 10 peels off the last digit.

System.out.println(5 / 2);     // 2   both int, so integer division
System.out.println(5 / 2.0);   // 2.5 one is a double, so double division
System.out.println(9 / 10);    // 0
System.out.println(17 % 5);    // 2   remainder after 3 whole fives
System.out.println(125 / 60);  // 2   whole minutes in 125 seconds
System.out.println(125 % 60);  // 5   seconds left over
Integer division truncates; modulo gives what is left behind.

Widening, narrowing and casting

Moving a value into a different type is safe one way and lossy the other.WIDENING — automaticint7double7.0double d = n;No digit can be lost, so Java doesthe conversion for you, silently.NARROWING — you must castdouble7.9(int)int7int k = (int) d;Digits WILL be lost, so Java refusesto guess — write the cast yourself.(int) chops toward zero. It never rounds.7897.27.9To round instead: Math.round(7.9) gives 8.Everything from 7.0 to 7.999 casts to 7.
Fig 3Widening happens automatically; narrowing must be requested with a cast and can lose data.

Moving a value into a larger type is safe, so Java does it automatically. This is implicit widening, and it follows the chain byte → short → int → long → float → double, with char joining at int. Moving a value into a smaller type risks losing information, so Java refuses unless you explicitly demand it with a cast: the target type written in brackets in front of the value. The cast is you signing off on the loss.

int count = 7;
double d = count;               // implicit widening: d is 7.0

double price = 9.99;
int dollars = (int) price;      // explicit narrowing: 9, the .99 is discarded

int a = 7, b = 2;
double wrong = a / b;           // 3.0 — the division already happened in int
double right = (double) a / b;  // 3.5 — a becomes 7.0, so b widens to match

char letter = 'A';
int code = letter;              // 65, the numeric code for 'A'
char next = (char) (code + 1);  // 'B'
A cast affects only the value it is attached to, and it acts before the division runs.
A cast truncates, it does not round
(int) 9.99 is 9 and (int) -3.7 is -3, because a cast simply deletes the fractional part and moves toward zero. If you want rounding, use Math.round first and cast the result. Casting is also blind to range: (byte) 300 gives 44, because 300 does not fit in eight bits and the extra bits are thrown away.

Worked examples

Reveal one step at a time and try to beat it to the next line.

Example 1
A student stores a mark of 17 out of 20 and writes int percent = mark / total * 100;. It prints 0. Explain and fix it, then produce a version that keeps the decimal.
Example 2
Convert 3 725 seconds into hours, minutes and seconds using only int arithmetic.
Example 3
State the value and type produced by each of (int) 7.99, (double) 9 / 2, (int) (9 / 2) and (char) 66.

Where marks get lost

  • Expecting 5 / 2 to be 2.5. With two ints Java truncates to 2 — and never warns you, because nothing illegal happened.
  • Casting too late: (double) (a / b) does the integer division first, so the decimal is already gone by the time the cast runs.
  • Assuming a cast rounds. (int) 9.99 is 9, not 10. Use Math.round when you want rounding.
  • Storing a value that overflows an int — anything past 2 147 483 647 wraps to a negative number silently. Use long.
  • Using == to compare Strings because String looks like a primitive. It is a class, so .equals() is the correct tool.

Flashcards 10

Name the eight primitive types.
Why is String not a primitive?
What is 5 / 2 in Java?
How do you force decimal division on two ints a and b?
+ 6 more

Practice

1
What value does 7 / 2 produce when both operands are ints?
2
What is the value of 23 % 5?
3
What does (double) 7 / 2 evaluate to?
4
What int value does (int) 4.99 produce?
5
Which statement correctly declares a constant for Ontario's 13% HST rate?
6
Which of these is NOT one of Java's eight primitive types?
7
A char variable holds 'A'. What int value do you get from (int) 'A'?
8
What does System.out.println(5 / 2.0); print?
9
An int holds 2147483647 and the program adds 1. What is stored?
10
Put these primitive types in order of widening, from narrowest to widest.
  1. 1float
  2. 2long
  3. 3double
  4. 4byte
  5. 5short
  6. 6int
11
Match each type to the job it is best suited for.
int
double
boolean
char
12
Rewrite int avg = total / count; so the average keeps its decimal places in a double named avg.

Spot a mistake on this page? Let us know