Java Operators

Su Suriya Ravichandran Updated 14 Nov 2026
9 min read ·Lesson 10 of 133

Operators are symbols that perform operations on values. Java groups them by what they do: arithmetic, assignment, comparison, logical, bitwise, and a few special cases. Each group has rules about operand types, result types, and evaluation order that determine what an expression actually computes.

Arithmetic Operators

OperatorOperationExampleResult
+Addition7 + 29
-Subtraction7 - 25
*Multiplication7 * 214
/Division7 / 23
%Remainder (modulus)7 % 21

Integer division

When both operands are integers, / discards the fractional part:

System.out.println(7 / 2);      // 3
System.out.println(-7 / 2);     // -3  (truncates toward zero)
System.out.println(7 / 2.0);    // 3.5 (one operand is double)
System.out.println(7 / 0);      // ArithmeticException: / by zero
System.out.println(7 / 0.0);    // Infinity (floating-point division by zero does not throw)

Remainder

% returns what is left after integer division. Its sign follows the left operand:

System.out.println(7 % 3);      // 1
System.out.println(-7 % 3);     // -1
System.out.println(7 % -3);     // 1
System.out.println(7.5 % 2);    // 1.5 (works on doubles too)

Common uses: n % 2 == 0 tests for even numbers; i % size wraps an index around a circular buffer; seconds % 60 extracts the seconds part of a duration. For a result that is always non-negative, use Math.floorMod(-7, 3), which gives 2.

Unary plus and minus

int a = 5;
int b = -a;    // -5
int c = +a;    // 5 (no effect; exists for symmetry)

Increment and Decrement

++ adds one; -- subtracts one. Each has a prefix and a postfix form that differ in what value the expression yields.

int i = 5;
int a = i++;   // a is 5, then i becomes 6  (postfix: use, then increment)
int b = ++i;   // i becomes 7, then b is 7  (prefix: increment, then use)

As a standalone statement (i++;) the two are identical. The difference matters only when the result is used in a larger expression, and code that depends on it (arr[i++] = x;) is harder to read than two separate statements.

Assignment Operators

= stores a value. The compound forms combine an operation with assignment:

OperatorEquivalent
x += yx = x + y
x -= yx = x - y
x *= yx = x * y
x /= yx = x / y
x %= yx = x % y
x &= y, x |= y, x ^= yBitwise and/or/xor with assignment
x <<= y, x >>= y, x >>>= yShift with assignment

Compound assignment includes an implicit cast back to the variable's type, so byte b = 10; b += 5; compiles while b = b + 5; does not.

Assignment is itself an expression whose value is the assigned value, so it chains:

int x, y, z;
x = y = z = 0;   // evaluated right to left

Writing = where == was intended is a compile error in a condition because an int is not a boolean. The exception is boolean variables: if (flag = true) compiles and always assigns true. Write if (flag) instead.

Comparison Operators

All comparison operators produce a boolean.

OperatorMeaning
==Equal to
!=Not equal to
>Greater than
<Less than
>=Greater than or equal to
<=Less than or equal to
int age = 20;
boolean adult = age >= 18;      // true
boolean teen = age >= 13 && age <= 19;   // false

<, >, <=, >= work only on numeric types (including char). == and != work on everything, with one critical distinction:

  • On primitives, == compares values.
  • On references, == compares identity: whether both variables point at the same object.
String s1 = new String("hi");
String s2 = new String("hi");
System.out.println(s1 == s2);        // false: two different objects
System.out.println(s1.equals(s2));   // true: same content

Use equals to compare the content of objects (String, Integer, LocalDate, your own classes). Use == for primitives, for null checks (x == null), and for enum constants, which are guaranteed unique.

Logical Operators

Logical operators combine boolean values.

OperatorMeaningtrue when
&&ANDBoth operands are true
||ORAt least one operand is true
!NOTThe operand is false
boolean loggedIn = true;
boolean isAdmin = false;

System.out.println(loggedIn && isAdmin);   // false
System.out.println(loggedIn || isAdmin);   // true
System.out.println(!isAdmin);              // true

Short-circuit evaluation

&& and || evaluate the right operand only if needed. If the left side of && is false, the result is false regardless, so the right side is skipped. If the left side of || is true, the right side is skipped.

String name = null;
if (name != null && name.length() > 0) {   // safe: length() is never called on null
    System.out.println(name);
}

Without short-circuiting, name.length() would throw NullPointerException. Ordering conditions so that the cheap or guarding check comes first is a standard pattern.

The single-character forms & and | also work on booleans but evaluate both sides always. They are rarely wanted for logic; their main use is bitwise arithmetic on integers.

Ternary (Conditional) Operator

condition ? valueIfTrue : valueIfFalse is the only operator with three operands. It is an expression, so it produces a value.

int score = 72;
String result = score >= 50 ? "pass" : "fail";

int max = a > b ? a : b;

Both branches must produce compatible types. It replaces a four-line if/else that merely assigns a variable. Nesting ternaries (a ? b : c ? d : e) is legal but hard to read; use if/else or a switch expression for more than two outcomes.

Bitwise and Shift Operators

These operate on the individual bits of integer types. They appear in low-level code: flags, masks, compression, hashing, networking, graphics.

OperatorName5 op 3 (binary 101, 011)
&AND001 = 1
|OR111 = 7
^XOR110 = 6
~NOT (complement)~5 = -6
<<Left shift5 << 1 = 10
>>Signed right shift-8 >> 1 = -4
>>>Unsigned right shift-8 >>> 28 = 15
int read = 0b100, write = 0b010, exec = 0b001;
int perms = read | write;          // 0b110: combine flags
boolean canWrite = (perms & write) != 0;   // test a flag
perms &= ~write;                   // clear a flag: 0b100

Left-shifting by n multiplies by 2ⁿ; right-shifting divides by 2ⁿ. >> preserves the sign bit (arithmetic shift); >>> fills with zeros (logical shift). The shift amount is taken modulo 32 for int and modulo 64 for long, so 1 << 33 on an int is 1 << 1.

String Concatenation

+ with at least one String operand produces a new String:

String s = "Total: " + 5 + 3;       // "Total: 53"
String t = "Total: " + (5 + 3);     // "Total: 8"
String u = 5 + 3 + " items";        // "8 items"

Evaluation is left to right. In s, "Total: " + 5 is already a string, so the final + 3 appends text. In u, 5 + 3 happens first because both are numbers. Any object concatenated to a string has its toString() called; null becomes the text "null".

instanceof

instanceof tests whether a reference refers to an object of a given type (or subtype, or implementing class):

Object o = "text";
if (o instanceof String s) {     // pattern matching form, Java 16+
    System.out.println(s.length());
}

null instanceof Anything is always false.

Operator Precedence

When an expression contains several operators, precedence determines which is applied first. Higher rows bind tighter.

PrecedenceOperatorsAssociativity
1 (highest)x++ x-- (postfix)Left
2++x --x +x -x ! ~ (unary)Right
3* / %Left
4+ -Left
5<< >> >>>Left
6< > <= >= instanceofLeft
7== !=Left
8&Left
9^Left
10|Left
11&&Left
12||Left
13? :Right
14 (lowest)= += -= etc.Right
int r = 2 + 3 * 4;          // 14, not 20: * before +
boolean b = 5 > 3 && 2 > 1; // comparisons before &&
int m = 10 - 4 - 3;         // 3: left associative, (10 - 4) - 3

Two practical rules follow from the table:

  1. Arithmetic binds tighter than comparison, which binds tighter than logical operators. a + b > c && d is ((a + b) > c) && d with no parentheses needed.
  2. Bitwise & and | bind looser than ==. flags & MASK == 0 is parsed as flags & (MASK == 0), which is a compile error. Always write (flags & MASK) == 0.

When precedence is not obvious to a reader, add parentheses. They cost nothing at runtime and prevent misreading.

Evaluation Order

Separately from precedence, Java guarantees that operands are evaluated left to right, and that an operator's operands are fully evaluated before the operator is applied.

int i = 1;
int result = i++ + i++;   // 1 + 2 = 3, and i is 3 afterward

The left i++ yields 1 and sets i to 2; the right i++ yields 2 and sets i to 3. This is well-defined in Java (unlike C, where it is undefined behavior), but code that relies on it is confusing and should be split into separate statements.

Method arguments are also evaluated left to right, so f(a(), b()) always calls a before b.

Practical Example

public class PriceCalculator {
    public static void main(String[] args) {
        double unitPrice = 24.99;
        int quantity = 4;
        boolean isMember = true;
        int couponPercent = 15;

        double subtotal = unitPrice * quantity;
        double discount = isMember ? subtotal * couponPercent / 100.0 : 0;
        double total = subtotal - discount;

        boolean freeShipping = total >= 75 || (isMember && quantity > 2);
        int whole = (int) total;
        int cents = (int) Math.round((total - whole) * 100);

        System.out.printf("Subtotal: %.2f%n", subtotal);
        System.out.printf("Discount: %.2f%n", discount);
        System.out.printf("Total: %d.%02d%n", whole, cents);
        System.out.println("Free shipping: " + freeShipping);
    }
}

Output:

Subtotal: 99.96
Discount: 14.99
Total: 84.97
Free shipping: true

subtotal * couponPercent / 100.0 is evaluated left to right: the multiplication happens first, then the division by a double, so no integer truncation occurs. The ternary gives a discount of zero to non-members. || short-circuits: once total >= 75 is true, the member check is skipped. %02d zero-pads the cents to two digits so 5 prints as 05.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about Java Operators and get answers drawn from it.

Signed-in readers only.