What you'll learn
Every program is really just data being stored, changed, and combined. In this module you'll learn how Java holds data in variables, the exact types that data can take, and the operators you use to calculate and compare.
By the end you'll be able to:
- Declare, initialize, and reassign variables — and lock values with
final - Choose the right primitive type for any value
- Use literals, underscores in numbers, and
vartype inference - Convert between types safely with widening and narrowing casts
- Apply arithmetic, comparison, logical, and bitwise operators correctly
- Predict results using operator precedence, and use the
Mathclass
Note
Variables & constants
A variable is a named box in memory that holds a value. In Java every variable has a fixed type that never changes — this is what makes Java a statically typed language. You declare a variable by writing its type and name, and initialize it by giving it a value.
int age = 25; // declare + initialize
double price = 19.99;
char grade = 'A';
boolean isJavaFun = true;
age = 26; // reassign later
final int MAX = 100; // constant — cannot change
System.out.println(age);
System.out.println(grade + " costs " + price);A variable's value can change over time (that's why it's "variable"). When you want a value that must never change, mark it final — that makes it a constant. Constants are written in UPPER_SNAKE_CASE by convention.
Tip
totalPrice), not their type (doubleValue).Primitive data types
Java has 8 primitive types — the built-in building blocks for raw values. They fall into four natural groups:
Whole numbers
No decimals. int is the everyday default.
Decimal numbers
Fractions. double is the default.
Single character
One Unicode character, in single quotes.
True / false
Only true or false.
Each type reserves a fixed amount of memory, which decides the range of values it can hold:
| Type | Size | Holds | Example |
|---|---|---|---|
byte | 8-bit | -128 to 127 | byte b = 100; |
short | 16-bit | -32,768 to 32,767 | short s = 20000; |
int | 32-bit | ~ ±2.1 billion (the default) | int i = 42; |
long | 64-bit | very large whole numbers | long n = 9000000000L; |
float | 32-bit | decimals (less precise) | float f = 3.14f; |
double | 64-bit | decimals (the default) | double d = 3.14; |
char | 16-bit | one Unicode character | char c = 'A'; |
boolean | 1-bit* | true or false | boolean ok = true; |
byte small = 100;
short medium = 20_000;
int count = 2_000_000;
long huge = 9_000_000_000L; // note the L
float ratio = 3.14f; // note the f
double precise = 3.141592653589793;
char letter = 'J';
boolean active = false;
System.out.println(count + " / " + huge);
System.out.println(ratio + " / " + precise);Watch the suffixes
int by default, so a long literal larger than int's range needs an L. A decimal literal is a double by default, so a float needs an f.Literals, underscores & var
A literal is a fixed value written directly in code — 42, 3.14, 'A', true, "hello". To make large numbers readable you can add underscores as digit separators (the compiler ignores them): 1_000_000.
Since Java 10, you can use var for local variables and let the compiler infer the type from the value on the right. The variable is still strongly typed — you just didn't have to write the type twice.
var message = "Hello"; // inferred as String
var count = 42; // inferred as int
var pi = 3.14; // inferred as double
System.out.println(message.getClass().getSimpleName());
System.out.println(count + pi);Note
var only works when you initialize the variable immediately, and only for local variables (not fields or method parameters). Reach for it when the type is obvious from the value.Type conversion & casting
Sometimes you need to move a value from one type to another. There are two directions, and Java treats them very differently.
Widening →
Small into big is automatic and safe. No data is lost.
← Narrowing
Big into small needs an explicit cast and may lose data.
Widening (small type → bigger type) happens automatically because no information can be lost. Narrowing (big type → smaller type) must be requested with an explicit cast (type) — and it can lose data or overflow, so use it deliberately.
int i = 300;
byte b = (byte) i; // narrowing: 300 doesn't fit in a byte
System.out.println(b); // -> 44 (overflow wraps around)
double d = 9.99;
int truncated = (int) d; // decimals are dropped, not rounded
System.out.println(truncated); // -> 9
System.out.println(Integer.MAX_VALUE + 1); // overflowOverflow is silent
MAX_VALUE + 1 becomes the most negative number. Pick a type big enough for your data, or use long.Operators
Operators are the symbols that combine values. Arithmetic operators do the maths — but watch out for one classic trap:
| Operator | Meaning | Example → result |
|---|---|---|
+ | Addition | 5 + 2 → 7 |
- | Subtraction | 5 - 2 → 3 |
* | Multiplication | 5 * 2 → 10 |
/ | Division | 5 / 2 → 2 (int!) · 5.0 / 2 → 2.5 |
% | Modulo (remainder) | 5 % 2 → 1 |
int a = 17, b = 5;
System.out.println(a + b); // 22
System.out.println(a - b); // 12
System.out.println(a * b); // 85
System.out.println(a / b); // 3 <- integer division!
System.out.println(a % b); // 2 <- remainder
System.out.println((double) a / b); // 3.4Integer division truncates
/ throws away the remainder — 17 / 5 is 3, not 3.4. Make at least one side a double to get a decimal result.Comparison operators ask a yes/no question and produce a boolean, while logical operators combine those booleans:
| Comparison | Meaning | Logical | Meaning |
|---|---|---|---|
== | equal to | && | AND (both true) |
!= | not equal to | || | OR (either true) |
> | greater than | ! | NOT (flips it) |
>= | greater or equal | ||
< | less than | ||
<= | less or equal |
int age = 20;
boolean canVote = age >= 18;
boolean isTeen = age >= 13 && age <= 19;
System.out.println(canVote); // true
System.out.println(isTeen); // false
System.out.println(!canVote); // falseShort-circuiting
&& and || are lazy: if the left side already decides the answer, the right side isn't even evaluated. This is handy for guards like if (list != null && list.size() > 0).Java also has bitwise and shift operators that work on the individual bits of integers — useful for flags, low-level code, and performance tricks:
| Operator | Meaning |
|---|---|
& | Bitwise AND |
| | Bitwise OR |
^ | Bitwise XOR |
~ | Bitwise NOT (invert bits) |
<< | Left shift (× 2 each step) |
>> | Signed right shift (÷ 2 each step) |
>>> | Unsigned right shift |
Operator precedence & associativity
When several operators appear together, precedence decides who goes first (just like maths: * before +). Here's the order from highest to lowest, simplified:
| Level | Operators | Group |
|---|---|---|
| 1 | () ++ -- | Parentheses, postfix |
| 2 | ! ~ (type) | Unary, cast |
| 3 | * / % | Multiplicative |
| 4 | + - | Additive |
| 5 | < <= > >= | Relational |
| 6 | == != | Equality |
| 7 | && then || | Logical AND / OR |
| 8 | = += -= | Assignment |
Tip
* and / beat + and -, comparisons beat logic, and parentheses beat everything.The Math class
For anything beyond the basic operators, Java's built-in Math class has you covered — powers, roots, rounding, trigonometry, and more. Its methods are static, so you call them straight on Math:
System.out.println(Math.max(10, 20)); // 20
System.out.println(Math.min(10, 20)); // 10
System.out.println(Math.abs(-7)); // 7
System.out.println(Math.pow(2, 10)); // 1024.0
System.out.println(Math.sqrt(144)); // 12.0
System.out.println(Math.round(3.6)); // 4Note
Math.random() gives a random double from 0.0 up to (but not including) 1.0, and Math.PI is π. You'll use these constantly in real programs.Recap & quick check
Key takeaways
- A variable is a typed, named box for a value; final makes it a constant that can't change.
- Java has 8 primitives — int and double are the everyday defaults for numbers.
- Widening casts are automatic; narrowing casts are explicit and can overflow or lose data.
- Integer division drops the remainder — cast to double for a decimal result.
- Precedence decides evaluation order, but parentheses always win — use them for clarity.
Quick check
1. What is the result of the expression 7 / 2 in Java?
2. Which keyword makes a variable a constant that cannot be reassigned?
3. Converting a double to an int with (int) does what to the decimals?
4. What type does 'var total = 3.5;' infer?
5. Which operator gives the remainder of a division?
Great work — you can now store and manipulate data with confidence. Next up: Module 3 — Input, Output & Strings, where your programs start talking to the user and working with text.