Skip to content
elephantoo

Operators & expressions

Lesson 3 of 43 14 min read

Arithmetic, assignment, increment, comparison, logical and ternary operators, plus precedence.


Operators are the symbols that combine values into new values: + adds, > compares, && combines conditions. An expression is any piece of code that produces a value, like price * quantity or age >= 18. This lesson walks through every operator you will use day to day.

Arithmetic operators#

OperatorMeaningExampleResult
+addition (and string joining)7 + 29
-subtraction7 - 25
*multiplication7 * 214
/division7 / 23 (integer division!)
%remainder (modulo)7 % 21
Arithmetic.java
public class Arithmetic {
    public static void main(String[] args) {
        int a = 17, b = 5;
        System.out.println(a + b);
        System.out.println(a - b);
        System.out.println(a * b);
        System.out.println(a / b);          // integer division
        System.out.println(a % b);          // remainder
        System.out.println((double) a / b);
        System.out.println(-17 % 5);        // sign follows the left operand
        System.out.println(10 % 2 == 0);    // is 10 even?
    }
}
Output
22
12
85
3
2
3.4
-2
true

The remainder operator is handy: n % 2 == 0 tests for even numbers, and n % 10 gives the last digit.

Warning: integer division by zero (5 / 0) throws an ArithmeticException at runtime. Floating-point division by zero gives Infinity (or NaN for 0.0 / 0) instead.

Assignment and compound assignment#

= stores a value. Compound operators update a variable in place:

Java
int total = 10;
total += 5;   // total = total + 5  -> 15
total -= 3;   // total = total - 3  -> 12
total *= 2;   // total = total * 2  -> 24
total /= 5;   // total = total / 5  -> 4
total %= 3;   // total = total % 3  -> 1

Compound operators include a hidden cast. byte b = 10; b += 5; compiles, but b = b + 5; does not, because b + 5 is an int.

Increment and decrement#

++ adds one and -- subtracts one. The position matters when the expression's value is used:

Increment.java
public class Increment {
    public static void main(String[] args) {
        int i = 5;
        int a = i++;   // post-increment: use 5, then i becomes 6
        int b = ++i;   // pre-increment: i becomes 7, then use 7
        System.out.println(a + " " + b + " " + i);

        int count = 0;
        count++;       // on its own line, count++ and ++count behave the same
        System.out.println(count);
    }
}
Output
5 7 7
1

Tip: use ++/-- as standalone statements (i++;) and avoid burying them inside bigger expressions.

Comparison (relational) operators#

These always produce a boolean:

OperatorMeaning
==equal to
!=not equal to
<, >less than, greater than
<=, >=less than or equal, greater than or equal
Java
int age = 20;
boolean adult = age >= 18;   // true
boolean teen = age < 20;     // false

For objects such as String, == asks "is this the same object?" not "do they contain the same text?". Use a.equals(b) to compare contents. For double, avoid == on computed values; compare with a tolerance: Math.abs(x - y) < 1e-9.

Logical operators#

OperatorMeaningTrue when
&&ANDboth sides are true
||ORat least one side is true
!NOTthe operand is false
Logic.java
public class Logic {
    public static void main(String[] args) {
        int age = 25;
        boolean hasTicket = true;
        boolean isVip = false;

        System.out.println(age >= 18 && hasTicket);   // both true
        System.out.println(isVip || hasTicket);       // one is enough
        System.out.println(!isVip);

        String name = null;
        // Short-circuit: the right side is skipped because the left is false
        if (name != null && name.length() > 3) {
            System.out.println("Long name");
        } else {
            System.out.println("No name or short name");
        }
    }
}
Output
true
true
true
No name or short name

Short-circuiting means && stops at the first false and || stops at the first true. That is why name != null && name.length() > 3 never throws a NullPointerException. The single-character versions & and | always evaluate both sides; you will rarely want them on booleans.

The ternary operator#

condition ? valueIfTrue : valueIfFalse is a compact if/else that produces a value:

Java
int stock = 0;
String label = stock > 0 ? "In stock" : "Sold out";   // "Sold out"
int max = a > b ? a : b;                              // same as Math.max(a, b)

Keep ternaries short. Nesting them quickly becomes unreadable.

Bitwise and shift operators#

These work on the individual bits of integers. You will see them in low-level code, flags and hashing:

Bits.java
public class Bits {
    public static void main(String[] args) {
        int a = 0b1100;  // 12
        int b = 0b1010;  // 10
        System.out.println(a & b);   // AND  -> 1000 = 8
        System.out.println(a | b);   // OR   -> 1110 = 14
        System.out.println(a ^ b);   // XOR  -> 0110 = 6
        System.out.println(~a);      // NOT  -> -13
        System.out.println(1 << 4);  // shift left: 1 * 2^4 = 16
        System.out.println(-16 >> 2);  // signed shift right: -4
        System.out.println(-16 >>> 28); // unsigned shift right: 15
        System.out.println(Integer.toBinaryString(a));
    }
}
Output
8
14
6
-13
16
-4
15
1100

Operator precedence#

When an expression has several operators, precedence decides which runs first. From highest to lowest (simplified):

LevelOperators
1x++ x--
2++x --x ! unary - casts
3* / %
4+ -
5<< >> >>>
6< > <= >= instanceof
7== !=
8&, then ^, then |
9&&
10||
11? :
12= += -= etc.
Precedence.java
public class Precedence {
    public static void main(String[] args) {
        System.out.println(2 + 3 * 4);       // * first
        System.out.println((2 + 3) * 4);     // parentheses win
        System.out.println(10 - 4 - 3);      // left to right
        System.out.println("Sum: " + 2 + 3); // string joining left to right
        System.out.println("Sum: " + (2 + 3));
        System.out.println(2 + 3 + " apples");
    }
}
Output
14
20
3
Sum: 23
Sum: 5
5 apples

The last three lines are a classic trap. + is evaluated left to right, and as soon as one side is a String, it means "join". When in doubt, add parentheses. They cost nothing and make intent obvious.

Handy Math methods#

Java has no ^ power operator (^ is XOR!). Use the Math class instead:

MathDemo.java
public class MathDemo {
    public static void main(String[] args) {
        System.out.println(Math.pow(2, 10));
        System.out.println(Math.sqrt(144));
        System.out.println(Math.abs(-7));
        System.out.println(Math.max(3, 9) + " " + Math.min(3, 9));
        System.out.println(Math.round(2.5) + " " + Math.round(2.4));
        System.out.println(Math.floor(2.9) + " " + Math.ceil(2.1));
        System.out.println(Math.floorMod(-17, 5));
    }
}
Output
1024.0
12.0
7
9 3
3 2
2.0 3.0
3

Math.floorMod always returns a non-negative result for a positive divisor, which is often what you want for things like "wrap around a circular list".

Common mistakes#

  • Writing 2 ^ 3 expecting 8. It is XOR and gives 1. Use Math.pow(2, 3).
  • Using = (assignment) where you meant == (comparison). With ints the compiler catches it; with booleans, if (done = true) compiles and is always true!
  • Forgetting that "Total: " + a + b joins text instead of adding numbers.
  • Dividing integers when you wanted a decimal result.

What's next#

You can now build expressions. Next we make programs interactive by reading input from the keyboard with Scanner.

Check your understanding

Quick quiz

0/3 answered
  1. 1.What does this print? int x = 5; int y = x++ + ++x; System.out.println(y);

  2. 2.Why is if (obj != null && obj.isReady()) safe even when obj is null?

  3. 3.What is the value of 10 - 2 * 3 + 8 / 4?

Finished reading?

Mark this lesson complete to track your progress.