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.

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

OperatorMeaningExample
+ - * /Add, subtract, multiply, dividea * b
%Remainder7 % 3 is 1
++ --Increment, decrementi++
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 operand

Prefix and postfix

int i = 5;
System.out.println(i++);   // prints 5, then i becomes 6
System.out.println(++i);   // i becomes 7, then prints 7

Postfix 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 contents
For primitives == compares values. For references it compares identity, which is almost never what you want. Use equals for 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

OperatorMeaning
&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 in

Assignment operators

int n = 10;
n += 5;    // 15
n *= 2;    // 30

byte small = 10;
small += 300;    // compiles: a compound assignment includes a hidden cast

Compound 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. With boolean operands this compiles and silently assigns.
  • Comparing objects with ==, especially strings read from input.
  • Assuming + adds when one operand is a String. 1 + 2 + "x" is "3x" but "x" + 1 + 2 is "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

  1. Predict the output of System.out.println("Total: " + 1 + 2); and then of System.out.println("Total: " + (1 + 2));
  2. Why is if (list != null & list.size() > 0) unsafe?
  3. What is the value of 10 % -3, and which operand decides the sign?
  4. Rewrite x = x * 2 + 1; using a compound assignment, and say whether the two forms differ for a byte.

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.

Topics #Beginner #Java
Written by Lorens Mishra

Default administrator account created by the installer.

Continue reading

All Java notes →
Java

Introduction to Java

Java is a statically typed, object oriented language that compiles to bytecode and runs on a virtual machine, which is what makes it portable.

Read more

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.