Java · Beginner
Operators in Java
In short: Java operators combine values into expressions: arithmetic (+ - * / %), comparison (== != < > <= >=), logical (&& || !) and assignment (= += -=). Two int operands give an int result, / truncates toward zero, and && and || stop evaluating as soon as the answer is known.
Building expressions
An expression is any piece of code that produces a value, and operators are the symbols that combine smaller values into larger ones. Java's operators fall into a few groups, and most surprises come from two rules: the result type follows the operand types, and operators bind in a fixed order.
The arithmetic operators are +, -, *, / and %. When both operands are ints the result is an int, so 7 / 2 is 3, not 3.5; the fraction is discarded, which is called truncation. The remainder operator % gives what the division left over, so 7 % 2 is 1. Together the pair splits a quantity into units: minutes into hours and minutes, cents into euros and cents, a position into row and column. With a negative left operand, / truncates toward zero and % takes the sign of the left operand: -7 / 2 is -3 and -7 % 2 is -1. As soon as either operand is a double the other is widened and the result is a double, so 150 / 60.0 is 2.5.
+ also joins strings. If either operand is a String the other is converted to text and appended. Evaluation runs left to right, so "Sum: " + 2 + 3 becomes "Sum: 23", while 1 + 2 + " items" adds the numbers first because the string is reached last. Parentheses make the intent explicit.
= stores a value in a variable. The compound forms +=, -=, *=, /= and %= apply an operation and store the result in one step: rides += 2 means rides = rides + 2. ++ and -- add or subtract one. Use them as statements on their own line; x = i++ and x = ++i differ in whether x gets the old or the new value, and burying them inside larger expressions makes code hard to read.
Comparison operators produce a boolean: ==, !=, <, >, <= and >=. For primitives == compares values, and mixed int and double compare after widening, so 7 == 7.0 is true. For objects == asks whether two references point at the same object, which is rarely what you want for strings; the strings lesson explains equals.
The logical operators && (and), || (or) and ! (not) combine booleans. && and || short-circuit: when the left operand of && is false, the right is never evaluated, and likewise for || when the left is true. That is more than a speed trick. seatsLeft != 0 && 10 / seatsLeft > 1 is safe precisely because the division does not run when seatsLeft is zero. The single-character & and | also work on booleans but always evaluate both sides.
The conditional operator condition ? a : b picks one of two values. It is an expression, so it fits inside an assignment or a println argument, which an if statement cannot.
Precedence decides which operator applies first when there are no parentheses: *, / and % before + and -; arithmetic before comparisons; comparisons before &&, which comes before ||; assignment last. Operators of the same level apply left to right, except assignment, which goes right to left. When an expression makes you pause, add parentheses.
Syntax
a + b a - b a * b a / b a % b // arithmetic; int op int gives int
a == b a != b a < b a > b a <= b a >= b // comparison, result is boolean
a && b a || b !a // logical; && and || short-circuit
x = v x += v x -= v x *= v x /= v x %= v // assignment
x++ x-- // add or subtract one
condition ? valueIfTrue : valueIfFalse // conditional expression
"text" + value // string concatenationA boolean expression can only be built from booleans: if (count) with an int is a compile error, unlike in some other languages.
Arithmetic: minutes into hours and minutes
A bus timetable stores journey lengths in minutes. The program is run with the input 150.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int totalMinutes = in.nextInt();
int hours = totalMinutes / 60;
int minutes = totalMinutes % 60;
System.out.println(hours + " h " + minutes + " min");
double asHours = totalMinutes / 60.0;
System.out.println(asHours);
int rides = 5;
rides += 2;
rides++;
System.out.println(rides);
System.out.println(-7 / 2);
System.out.println(-7 % 2);
}
}Input given to the program: 150
Output
2 h 30 min 2.5 8 -3 -1
/ on two ints gives the whole hours and % gives the leftover minutes; that pairing is the standard way to split a total into units. Dividing by 60.0 instead of 60 turns the same calculation into a double. rides += 2 and rides++ change the variable in place. The last two lines show truncation toward zero and the remainder keeping the sign of the left operand.
Comparison, logic and short-circuiting
A concession check at a ticket desk. Watch the line that divides by seatsLeft.
public class Main {
public static void main(String[] args) {
int age = 17;
boolean hasPass = true;
int seatsLeft = 0;
System.out.println(age >= 18);
System.out.println(age >= 16 && hasPass);
System.out.println(seatsLeft > 0 || hasPass);
System.out.println(!hasPass);
boolean ok = seatsLeft != 0 && 10 / seatsLeft > 1;
System.out.println(ok);
String label = age >= 18 ? "adult" : "minor";
System.out.println(label);
}
}Output
false true true false false minor
Each comparison evaluates to a boolean that can be printed directly. In the ok line the left side seatsLeft != 0 is false, so && never evaluates 10 / seatsLeft; without short-circuiting that division by zero would throw an ArithmeticException. The conditional operator picks one of two strings based on the age.
Precedence and string concatenation
The same numbers, different results, depending on grouping and on where the string sits.
public class Main {
public static void main(String[] args) {
System.out.println(2 + 3 * 4);
System.out.println((2 + 3) * 4);
System.out.println("Sum: " + 2 + 3);
System.out.println("Sum: " + (2 + 3));
System.out.println(1 + 2 + " items");
int n = 10;
n -= 3;
n *= 2;
System.out.println(n);
System.out.println(7 == 7.0);
System.out.println(10 % 3 == 1);
}
}Output
14 20 Sum: 23 Sum: 5 3 items 14 true true
Multiplication binds tighter than addition, so 2 + 3 * 4 is 14. In "Sum: " + 2 + 3 the string comes first, so each number is appended as text; the parentheses in the next line force the numeric addition first. 1 + 2 + " items" adds first because the string is on the right. The compound assignments apply in order: 10 becomes 7, then 14. 7 == 7.0 is true because the int is widened before comparing, and % binds tighter than ==.
Precedence, highest first
| Level | Operators | Note |
|---|---|---|
| 1 | x++ x-- | postfix |
| 2 | ++x --x ! -x (type) | unary and cast |
| 3 | * / % | left to right |
| 4 | + - | also string concatenation |
| 5 | < <= > >= | relational |
| 6 | == != | equality |
| 7 | && | logical and |
| 8 | || | logical or |
| 9 | ? : | conditional |
| 10 | = += -= *= /= %= | right to left |
Common mistakes
Integer division where a fraction was wanted
Why it goes wrong:
double average = sum / count;with two int variables divides first, truncating to a whole number, and only then widens the result to double. 7 / 2 stored in a double is 3.0, not 3.5.Fix: Convert one operand before dividing.
Java · fixdouble average = (double) sum / count;Writing = instead of == in a condition
Why it goes wrong: With ints the compiler catches it (
int cannot be converted to boolean), butif (ready = true)compiles: it assigns true to ready and then tests it, so the block always runs.Fix: Compare booleans by using them directly:
if (ready)andif (!ready).Expecting % to return a non-negative result
Why it goes wrong:
-7 % 3is -1 in Java because the remainder keeps the sign of the left operand. Code that maps a value into a range with%breaks on negative input.Fix: Use
Math.floorMod(-7, 3), which returns 2, when the result must be in the range 0 to divisor minus one.Letting concatenation swallow an addition
Why it goes wrong:
"Total: " + price + taxprints the two numbers side by side instead of their sum, because once the string is reached every following+appends text.Fix: Put the arithmetic in parentheses:
"Total: " + (price + tax).
Where you use this
A checkout total is a small exercise in every operator group at once. Multiply quantity by unit price for the line total; decide with a comparison whether the order qualifies for a bulk discount; combine that with && so the discount only applies to members; use the conditional operator to pick the rate; and use / and % to present a total held in cents as euros and cents. Keeping money in whole cents in a long avoids the rounding errors of a double, and splitting the total into units is the same / and % pattern as the timetable.
long lineCents = quantity * unitCents;
boolean bulk = quantity >= 12 && member;
int discountPercent = bulk ? 10 : 0;
long totalCents = lineCents - lineCents * discountPercent / 100;
System.out.println(totalCents / 100 + "." + totalCents % 100);Key points
- int with int gives int:
7 / 2is 3 and7 % 2is 1; one double operand makes the result a double. /truncates toward zero and%keeps the sign of the left operand.+with a String operand concatenates; evaluation is left to right, so group arithmetic in parentheses.+=,-=,*=,/=,%=,++and--update a variable in place.- Comparisons yield booleans;
&&and||short-circuit,&and|do not. condition ? a : bis an expression that chooses a value.- Multiplication before addition, arithmetic before comparison,
&&before||; parentheses override everything.
Try it yourself
The program reads an amount in cents and prints only the whole euros. Change it to print E euro C cent, where C is the leftover cents, using %. For the input 1275 it should print 12 euro 75 cent.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int cents = in.nextInt();
System.out.println(cents / 100 + " euro");
}
}
127512 euro 75 centimport java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int cents = in.nextInt();
System.out.println(cents / 100 + " euro " + cents % 100 + " cent");
}
}
Practise this
Exercises for this lesson are in the Java practice set.
Related lessons
- Variables and Data Types in JavaJava's primitive types and String, declaring and initialising variables, var, casting and integer overflow: why the type you pick decides what a value can hold.9 min
- Conditions in Java: if, else and switchHow Java chooses between paths with if, else if and else, how the switch with arrows works, how to compare strings correctly and how to keep branches readable.9 min
- Strings in JavaHow Java strings work: immutability, the methods you use daily, why equals not == compares text, trimming and splitting input, StringBuilder and String.format.10 min
Frequently asked questions
What is the difference between && and & in Java?
Both give true only when both operands are true, but && stops as soon as the left operand is false, while & always evaluates both sides. Use && for conditions, especially when the right side could fail or is expensive, such as a check that only makes sense after a null or zero test. & on integers is a different operation entirely: it combines the bits of two numbers.
Why does 5 / 2 give 2 in Java?
Because both operands are ints, and integer division discards the fractional part. The result type of an arithmetic operator follows its operands, so Java never silently turns an int calculation into a decimal one. Write 5 / 2.0, 5.0 / 2 or (double) a / b when you want 2.5.
How this page was checked. Every program on it was run with OpenJDK 21 at build time by the publishing checks, and the output shown is what it printed. Running Java inside the browser is not available yet, so the Run button is absent rather than pretending; copy the code and run it with OpenJDK 21 locally.