Operators and Expressions in Java
Java operators grouped by purpose, with the precedence rules, short circuit behaviour and integer arithmetic surprises that trip people up.
-
Java Basics
- Introduction to Java
- Setting Up Java and Writing Your First Program
- Variables, Data Types and Literals in Java
- Type Casting and Type Conversion in Java
- Operators and Expressions in Java
- Input and Output in Java
- Comments, Keywords and Naming Conventions in Java
- Control Flow in Java: if, else and switch
- Loops in Java: for, while and do-while
- Methods
- Arrays and Strings
-
OOP
- Classes and Objects in Java
- Constructors in Java
- The this Keyword in Java
- The static Keyword in Java
- Encapsulation in Java
- Access Modifiers in Java
- Inheritance in Java
- Method Overriding and super in Java
- Polymorphism in Java
- Abstraction, Abstract Classes and Interfaces in Java
- Composition, Aggregation and Association in Java
- The Object Lifecycle in Java
- Core Java
- Exception Handling
-
Collections
- The Java Collections Framework
- List in Java: ArrayList, LinkedList, Vector and Stack
- Set in Java: HashSet, LinkedHashSet and TreeSet
- Map in Java: HashMap, LinkedHashMap and TreeMap
- How HashMap Works Internally in Java
- Queue and Deque in Java: ArrayDeque and PriorityQueue
- Iterators in Java
- Comparable and Comparator in Java
- Collections Utilities and Choosing the Right Collection
- Generics
- Java 8+
- Stream API
- Date and Time
- File and I/O
-
Multithreading
- Threads in Java: Processes, Runnable and Thread
- Thread Lifecycle in Java
- Synchronization in Java: synchronized and volatile
- Locks and Atomic Classes in Java
- Race Conditions and Deadlocks in Java
- The Executor Framework and Thread Pools in Java
- Future and CompletableFuture in Java
- Concurrent Collections in Java
- The Java Memory Model
- JVM and Memory
- Advanced Java
- Networking
- JDBC
- Testing
What an expression is
An expression is anything that produces a value. Operators combine expressions, and the type of the result is decided at compile time by the types of the operands.
Arithmetic operators
| Operator | Meaning | Example |
|---|---|---|
+ - * / | Add, subtract, multiply, divide | a * b |
% | Remainder | 7 % 3 is 1 |
++ -- | Increment, decrement | i++ |
System.out.println(7 / 2); // 3 integer division
System.out.println(7 % 2); // 1
System.out.println(-7 / 2); // -3 truncates towards zero
System.out.println(-7 % 2); // -1 the sign follows the left operandPrefix and postfix
int i = 5;
System.out.println(i++); // prints 5, then i becomes 6
System.out.println(++i); // i becomes 7, then prints 7Postfix yields the value before the change, prefix the value after. Never combine several of these on one variable in a single expression; the result is legal but unreadable.
Relational and equality operators
int a = 5, b = 9;
System.out.println(a < b); // true
System.out.println(a != b); // true
String x = new String("java");
String y = new String("java");
System.out.println(x == y); // false - two distinct objects
System.out.println(x.equals(y)); // true - equal contentsFor primitives==compares values. For references it compares identity, which is almost never what you want. Useequalsfor objects.
Logical operators and short circuit
boolean ok = (count > 0) && (total / count > 10);&& evaluates the right side only if the left side is true, and || only if the left side is false. That is short circuit evaluation, and it is what makes the guard above safe from division by zero. The single character forms & and | always evaluate both sides.
Bitwise and shift operators
| Operator | Meaning |
|---|---|
& | Bitwise AND |
| | Bitwise OR |
^ | Bitwise XOR |
~ | Bitwise complement |
<< | Left shift |
>> | Right shift, keeping the sign |
>>> | Right shift, filling with zeros |
System.out.println(-8 >> 1); // -4 the sign is preserved
System.out.println(-8 >>> 28); // 15 zeros are shifted inAssignment operators
int n = 10;
n += 5; // 15
n *= 2; // 30
byte small = 10;
small += 300; // compiles: a compound assignment includes a hidden castCompound assignment quietly narrows the result back to the target type. That convenience hides overflow, so it deserves a second look when the target is small.
The conditional operator
String label = score >= 50 ? "pass" : "fail";Precedence, briefly
From tightest to loosest, the groups met daily are:
postfix i++ i--
unary ++i --i + - ~ ! (cast)
multiplicative * / %
additive + -
shift << >> >>>
relational < > <= >= instanceof
equality == !=
bitwise & then ^ then |
logical && then ||
conditional ? :
assignment = += -= ...The practical rule is simpler than the table: reach for brackets whenever a reader would have to consult the table.
Common mistakes
- Using
=where==was meant. Withbooleanoperands this compiles and silently assigns. - Comparing objects with
==, especially strings read from input. - Assuming
+adds when one operand is aString.1 + 2 + "x"is"3x"but"x" + 1 + 2is"x12". - Using
&instead of&&in a guard and losing short circuit protection.
Best practices
- Bracket mixed arithmetic and logical expressions even when precedence is on your side.
- Keep increment and decrement as standalone statements.
- Order a compound condition so the cheap or protective test comes first.
Practice
- Predict the output of
System.out.println("Total: " + 1 + 2);and then ofSystem.out.println("Total: " + (1 + 2)); - Why is
if (list != null & list.size() > 0)unsafe? - What is the value of
10 % -3, and which operand decides the sign? - Rewrite
x = x * 2 + 1;using a compound assignment, and say whether the two forms differ for abyte.
Conclusion
Most operator bugs come from three places: integer division, == on references, and precedence assumed rather than checked. Watch those three and the rest is mechanical.