1. Boolean operations
The |
and &
operators can be applied not only to numbers, but also to boolean expressions.
But, as you already know, there are &&
and ||
operators. Why would we use |
instead of ||
, and &
instead of &&
? Is there any point to this? It seems that there is. Sometimes.
The ||
and &&
logical operators are executed from left to right following a so-called lazy principle.
(expression1) || (expression2) || (expression3)
If expression1
is equal to true
, there is no point in evaluating expression2
and expression3
: the result will be true
regardless.
Accordingly, when evaluating expressions (they are evaluated from left to right), as soon as we get true
, the evaluation of the rest of the expressions is skipped. And if expression2
and expression3
include method calls, these methods won't be called!
The same goes for the &&
logical operator:
(expression1) && (expression2) && (expression3)
If expression1
is equal to false
, there is no point in evaluating expression2
and expression3
: the result will be false
regardless.
This is an important fact that lets you write things like:
String s = null;
if (s != null && s.length() > 0) {
The example above will never get you a NullPointerException, because s.length()
will only be executed if the first part s! = null
is true
.
If s
is equal to null
, the part to the left of the &&
operator is false
, then the result of the whole boolean expression is false
, so the part to the right (s.length() > 0
) is not evaluated.
If you use the |
operator or the &
operator, then there is no lazy evaluation: each subexpression will always be evaluated.
2. Operation precedence in Java
As you probably remember from your high school math class, the multiplication operator has higher precedence than the addition operator. Parentheses have an even higher precedence: expressions in parentheses are evaluated first, then multiplication and division, and then addition and subtraction.
Operators in Java also have a order of precedence. The difference is that a) there are slightly more of them, b) for some operators, the operands are evaluated from left to right, while for others — from right to left.
Here is a table with all the Java operators:
Category | Operator | Associative |
---|---|---|
Postfix | () [] . |
From left to right |
Unary | ++ -- ! ~ |
Right to left |
Multiplicative | * / % |
From left to right |
Additive | + - |
From left to right |
Shifting | >> >>> << |
From left to right |
Relational | > >= < <= |
From left to right |
Equality | == != |
From left to right |
Bitwise AND |
& |
From left to right |
Exclusive OR (XOR) |
^ |
From left to right |
Bitwise OR |
| |
From left to right |
Logical AND |
&& |
From left to right |
Logical OR |
|| |
From left to right |
Conditional | ?: |
Right to left |
Assignment | = += -= *= /= %= >>= <<= &= ^= |= |
Right to left |
Comma | , |
From left to right |
The top line contains the operators with the highest precedence. Parentheses ()
are used to explicitly set the priority. Square brackets []
are used to access an element at a specific index of an array variable. The dot operator (.
) is used to access fields and methods using a reference to an object or class.
The lower the operators are in the table, the lower their precedence.
If you use multiple operators in an expression, don't be lazy: add parentheses.
In Java, you can write something like if (a & 1<< b > ~c)
, but you shouldn't. You're writing code not only for the compiler, but also for other programmers. The more readable the code, the better.
3. Prefix and postfix increment
As you already know, Java has an increment operator (++
) and a decrement operator (--
). Respectively, they increase and decrease the value of a variable by 1
.
What you probably don't know is that there are two types of these operators: prefix (the operator is placed before the variable) and postfix (the operator is placed after the variable). And two kinds of operators work a little differently.
In Java, you can write an expression like this:
int a = 5;
int b = a++;
If the ++
operator appears after a variable and the variable is part of some expression (as in the example above), then the expression will use the current value of the variable, and only afterward will the variable be increased by 1
.
In other words, something like this will happen:
int a = 5;
int b = a;
a = a + 1;
That is, b
will be 5
, not 6
as you might think at first glance.
If the ++
operator is before the variable and the variable is part of some expression, it will first be increased by 1
and only afterward will its value be used in the expression.
int a = 5;
int b = ++a;
The example above is equivalent to the following example:
int a = 5;
a = a + 1;
int b = a;
Here, b
will be equal to 6
.
There's even an example used by Java programmers to determine whether someone else is also a Java programmer:
int a = 5;
int b = ++a + ++a;
Yep, you can write that too.
This example will compile just fine and turn into something like this:
int a = 5;
a = a + 1;
int v1 = a;
a = a + 1;
int v2 = a;
int b = v1 + v2;
For the --
operator, everything is exactly the same.
GO TO FULL VERSION