Operators All Versions
This draft deletes the entire topic.
Examples
-
Variables can be incremented or decremented by 1 using the
++
and--
operators, respectively.When the
++
and--
operators follow variables, they are called post-increment and post-decrement respectively.int a = 10; a++; // a now equals 11 a--; // a now equals 10 again
When the
++
and--
operators precede the variables the operations are called pre-increment and pre-decrement respectively.int x = 10; --x; // x now equals 9 ++x; // x now equals 10
If the operator precedes the variable, the value of the expression is the value of the variable after being incremented or decremented. If the operator follows the variable, the value of the expression is the value of the variable prior to being incremented or decremented.
int x=10; System.out.println("x=" + x + " x=" + x++ + " x=" + x); // outputs x=10 x=10 x=11 System.out.println("x=" + x + " x=" + ++x + " x=" + x); // outputs x=11 x=12 x=12 System.out.println("x=" + x + " x=" + x-- + " x=" + x); // outputs x=12 x=12 x=11 System.out.println("x=" + x + " x=" + --x + " x=" + x); // outputs x=11 x=10 x=10
Be careful not to overwrite post-increments or decrements. This happens if you use a post-in/decrement operator at the end of an expression which is reassigned to the in/decremented variable itself. The in/decrement will not have an effect. Even though the variable on the left hand side is incremented correctly, its value will be immediately overwritten with the previously evaluated result from the right hand side of the expression:
int x = 0; x = x++ + 1 + x++; // x = 0 + 1 + 1 // do not do this - the last increment has no effect (bug!) System.out.println(x); // prints 2 (not 3!)
Correct:
int x = 0; x = x++ + 1 + x; // evaluates to x = 0 + 1 + 1 x++; // adds 1 System.out.println(x); // prints 3
-
Syntax
{condition-to-evaluate} ? {statement-executed-on-true} : {statement-executed-on-false}
As shown in the syntax, the Conditional Operator (also known as the Ternary Operator1) uses the
?
(question mark) and:
(colon) characters to enable a conditional expression of two possible outcomes. It can be used to replace longerif-else
blocks to return one of two values based on condition.result = testCondition ? value1 : value2
Is equivalent to
if (testCondition) { result = value1; } else { result = value2; }
It can be read as “If testCondition is true, set result to value1; otherwise, set result to value2”.
While the conditional operator can at times be a nice replacement for an if/else statement, the conditional operator may be at its most useful as an operator on the right hand side of a statement. For example:
// get absolute value using conditional operator a = -10; int absValue = (a < 0) ? -a : a; System.out.println("abs = " + absValue); // prints "abs = 10"
Is equivalent to
// get absolute value using if/else loop a = -10; int absValue = 0; if(a < 0) { absValue = -a; } else { absValue = a; } System.out.println("abs = " + absValue); // prints "abs = 10"
Common Usage
You can use the conditional operator for conditional assignments (like null checking).
String x = (y != null) ? y.toString() : ""; //where y is an object
This example is equivalent to:
String x = ""; if (y != null) { x = y.toString(); }
Conditional operators nesting can also be done in the third part, where it works more like chaining or like a switch statement.
a ? "a is true" : b ? "a is false, b is true" : c ? "a and b are false, c is true" : "a, b, and c are false" //Operator precedence can be illustrated with parenthesis: a ? x : (b ? y : (c ? z : w))
Footnote:
1 - Both the Java Language Specification and the Java Tutorial call the (
? :
) operator the Conditional Operator. The Tutorial says that it is "also known as the Ternary Operator" as it is (currently) the only ternary operator defined by Java. The "Conditional Operator" terminology is consistent with C and C++ and other languages with an equivalent operator. -
-
The Java language provides 4 operators that perform bitwise logical operations on integer operands operands.
- The bitwise complement (
~
) operator is a unary operator that performs a bitwise inversion of the bits of one operand; see JLS 15.15.5.. - The bitwise AND (
&
) operator is a binary operator that performs a bitwise "and" of two operands; see JLS 15.22.2.. - The bitwise OR (
|
) operator is a binary operator that performs a bitwise "inclusive or" of two operands; see JLS 15.22.2.. - The bitwise XOR (
^
) operator is a binary operator that performs a bitwise "exclusive or" of two operands; see JLS 15.22.2..
The logical operations performed these operators can be summarized as follows:
A B ~A A & B A | B A ^ B 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 1 1 1 0 1 1 0 Note that the above table describes what happens for individual bits. The operators actually operate on all 32 or 64 bits of the operand or operands in parallel.
Operand types and result types.
As we stated above, these 4 operators apply to integer operands. (There are 3 overloaded operators for non-short-circuit logical operations, but the Java Language Specification treats them as separate operators.)
In fact, Java only supports integer bitwise operations for
int
andlong
values. The operands are are converted as follows:- A
byte
,short
orchar
operand is promoted toint
, - A
Byte
Short
orCharacter
operand is unboxed and promoted toint
. - An
Integer
is unboxed to anint
. - An
Long
is unboxed to along
.
For the unary operator, the type of the converted operand determines the type of the result.
For the binary operators:
- If both operands are
int
, a 32 bit operation is performed giving anint
result. - If both operands are
long
a 64 bit operation is performed, giving anlong
result. - One operand is
int
and the other islong
, theint
operand is promoted tolong
. Then a 64 bit operation is performed, giving along
result.
This means that if you perform a bitwise operation on a
byte
,short
orchar
, you cannot directly assign the result to abyte
,short
orchar
variable. For example:byte b = 0x11; b = b & 0x01; // COMPILATION ERROR
The solution is to cast the result of the bitwise operation before assigning; e.g.
b = (byte) (b & 0x01); // CORRECT
Common use-cases for the bitwise operators
The
~
operator is rarely used on its own.The
&
operator is often used for "masking out" some of the bits in a word represented as an integer. For example:int word = 0b00101010; int mask = 0b00000011; // Mask for masking out all but the bottom // two bits of a word int lowBits = word & mask; // -> 0b00000010 int highBits = word & ~mask; // -> 0b00101000
The
|
operator is often used for combining part of one word with another. For example:int word2 = 0b01011111; // Combine the bottom 2 bits of word1 with the top 30 bits of word2 int combined = (word & mask) | (word2 & ~mask); // -> 0b01011110
The
^
operator is most often used for toggling or "flipping" bits:int word3 = 0b00101010; int word4 = word3 ^ mask; // -> 0b00101001
The
^
operator is also used in some hashing algorithms.For more examples of the use of the bitwise operators, see Bit Manipulation
- The bitwise complement (
-
Description Operators / constructs Level grouping & accessing ( ) [ ] . 16 postfix expr++ expr-- 15 unary ++expr --expr +expr -expr ~ ! 14 multiplicative * / % 13 additive + - 12 shift << >> >>> 11 relational < > <= >= instanceof 10 equality == != 9 bitwise AND & 8 bitwise exclusive OR ^ 7 bitwise inclusive OR | 6 logical AND && 5 logical OR || 4 ternary ? : 3 assignment = += -= *= /= %= &= ^= |= <<= >>= >>>= 2 lambda -> 1 Higher level means higher precedence
(Technically speaking, the symbols
(
,)
,[
,]
and.
are not classified as operators in Java. see JLS 3.11.)
Given an expressions
expr
with more than one operator -- the higher the operator precedence (level), the sooner it is evaluated inexpr
. In case two operators ofexpr
have the same precedence, the evaluation is from left to right, as the following example shows:int x = 11; int expr = 20 / --x + 5 * 4 % 6; // 4
where:
--x
has the higher precedence (level 13) so it is evaluated before any other operator inexpr
, and therefore before/
;*
,/
and%
have all the same precedence (level 12), so5*4%6
is evaluated from left to right;+
(level 11) has a lower precedence than*
,/
and%
so it is evaluated afterwards;=
(level 1) has the lower precedence inexpr
, so it is the last evaluated operator.
Parentheses,
(
and)
, can be used to make the meaning of an expression more obvious:int x1 = 11; int expr1 = 20 / (--x1) + (5 * 4) % 6; // 4 - same result as expr, but easier // to understand for many
They can also be used to override the normal operator precedence:
int x2 = 11; int expr2 = 20 / (--x2 + 5 * 4) % 6; // 0 - different result
-
The
+
symbol can mean three distinct operators in Java:- If there is no operand before the
+
, then it is the unary Plus operator. - If there are two operands, and they are both numeric. then it is the binary Addition operator.
- If there are two operands, and at least one of them is a
String
, then it it the binary Concatenation operator.
In the simple case, the Concatenation operator joins two strings to give a third string. For example:
String s1 = "a String"; String s2 = "This is " + s1; // s2 contains "This is a String"
When one of the two operands is not a string, it is converted to a
String
as follows:-
An operand whose type is a primitive type is converted as if by calling
toString()
on the boxed value. -
An operand whose type is a reference type is converted by calling the operand's
toString()
method. If the operand isnull
, or if thetoString()
method returnsnull
, then the string literal"null"
is used instead.
For example:
int one = 1; String s3 = "One is " + one; // s3 contains "One is 1" String s4 = null + " is null"; // s4 contains "null is null" String s5 = "{1} is " + new int[]{1}; // s5 contains something like // "{} is [I@xxxxxxxx"
The explanation for the
s5
example is that thetoString()
method on array types is inherited fromjava.lang.Object
, and the behavior is to produce a string that consists of the type name, and the object's identity hashcode.The Concatenation operator is specified to create a new
String
object, except in the case where the expression is a Constant Expression. In the latter case, the expression is evaluated at compile type, and its runtime value is equivalent to a string literal. This means that there is no runtime overhead in splitting a long string literal like this:String typing = "The quick brown fox " + "jumped over the " + "lazy dog"; // constant expression
Optimization and efficiency
As noted above, with the exception of constant expressions, each string concatenation expression creates a new
String
object. Consider this code:public String stars(int count) { String res = ""; for (int i = 0; i < count; i++) { res = res + "*"; } return res; }
In the method above, each iteration of the loop will create a new
String
that is one character longer than the previous iteration. Each concatenation copies all of the characters in the operand strings to form the newString
. Thus,stars(N)
will:- create
N
newString
objects, and throw away all but the last one, - copy
N * (N + 1) / 2
characters, and - generate
O(N^2)
bytes of garbage.
This is very expensive for large
N
. Indeed, any code that concatenates strings in a loop is liable to have this problem. A better way to write this would be as follows:public String stars(int count) { // Create a string builder with capacity 'count' StringBuilder sb = new StringBuilder(count); for (int i = 0; i < count; i++) { sb.append("*"); } return sb.toString(); }
Ideally, you should set the capacity of the
StringBuilder
, but if this is not practical, the class will automatically grow the backing array that the builder uses to hold characters. (Note: the implementation expands the backing array exponentially. This strategy keeps that amount of character copying to aO(N)
rather thanO(N^2)
.)Some people apply this pattern to all string concatenations. However, this is unnecessary because the JLS allows a Java compiler to optimize string concatenations within a single expression. For example:
String s1 = ...; String s2 = ...; String test = "Hello " + s1 + ". Welcome to " + s2 + "\n";
will typically be optimized by the bytecode compiler to something like this;
StringBuilder tmp = new StringBuilder(); tmp.append("Hello ") tmp.append(s1 == null ? "null" + s1); tmp.append("Welcome to "); tmp.append(s2 == null ? "null" + s2); tmp.append("\n"); String test = tmp.toString();
(The JIT compiler may optimize that further if it can deduce that
s1
ors2
cannot benull
.) But note that this optimization is only permitted within a single expression.In short, if you are concerned about the efficiency of string concatenations:
- Do hand-optimize if you are doing repeated concatenation in a loop (or similar).
- Don't hand-optimize a single concatenation expression.
- If there is no operand before the
-
This operator checks whether the object is of a particular class/interface type. instanceof operator is written as:
( Object reference variable ) instanceof (class/interface type)
Example:
public class Test { public static void main(String args[]){ String name = "Buyya"; // following will return true since name is type of String boolean result = name instanceof String; System.out.println( result ); } }
This would produce the following result:
true
This operator will still return true if the object being compared is the assignment compatible with the type on the right.
Example:
class Vehicle {} public class Car extends Vehicle { public static void main(String args[]){ Vehicle a = new Car(); boolean result = a instanceof Car; System.out.println( result ); } }
This would produce the following result:
true
-
Java provides 6 logical operators; i.e., operators that take one or two operands of type
boolean
and produce aboolean
result. These are:!
- the NOT operator,&
and&&
- the AND operators,|
and||
- the inclusive OR operators, and^
- the exclusive OR operator.
The values produced by these operators are given the following "truth table".
X Y !X X && Y
X & YX || Y
X | YX ^ Y true true false true true false true false false false true true false true true false true true false false true false false false The difference between the regular (
&
and|
) and short-circuit (&&
and||
) operators is in the way that the operand expressions are evaluated:-
The evaluation of
<left-expr> & <right-expr>
is equivalent to the following pseudo-code:{ boolean L = evaluate(<left-expr>); boolean R = evaluate(<right-expr>); return L AND R; }
-
The evaluation of
<left-expr> && <right-expr>
is equivalent to the following pseudo-code:{ boolean L = evaluate(<left-expr>); if (L) { return evaluate(<right-expr>); } else { // short-circuit the evaluation of the 2nd operand expression return false; } }
-
The evaluation of
<left-expr> | <right-expr>
is equivalent to the following pseudo-code:{ boolean L = evaluate(<left-expr>); boolean R = evaluate(<right-expr>); return L OR R; }
-
The evaluation of
<left-expr> || <right-expr>
is equivalent to the following pseudo-code:{ boolean L = evaluate(<left-expr>); if (!L) { return evaluate(<right-expr>); } else { // short-circuit the evaluation of the 2nd operand expression return true; } }
As the pseudo-code above illustrates, the behavior of the short-circuit operators are equivalent to using
if
/else
statements.Example - using && as a guard in an expression
The following example shows the most common usage pattern for the
&&
operator. Compare these two versions of a method to test if a suppliedInteger
is zero.public boolean isZero(Integer value) { return value == 0; } public boolean isZero(Integer value) { return value != null && value == 0; }
The first version works in most cases, but if the
value
argument isnull
, then aNullPointerException
will be thrown.In the second version we have added a "guard" test. The
value != null && value == 0
expression is evaluated by first performing thevalue != null
test. If thenull
test succeeds (i.e. it evaluates totrue
) then thevalue == 0
expression is evaluated. If thenull
test fails, then the evaluation ofvalue == 0
is skipped (short-circuited), and we don't get aNullPointerException
.Example - using && to avoid a costly calculation
The following example shows how
&&
can be used to avoid a relatively costly calculation:public boolean verify(int value, boolean needPrime) { return !needPrime | isPrime(value); } public boolean verify(int value, boolean needPrime) { return !needPrime || isPrime(value); }
In the first version, both operands of the
|
will always be evaluated, so the (expensive)isPrime
method will be called unnecessarily. The second version avoids the unnecessary call by using||
instead of|
. -
The Java language provides 7 operators that perform arithmetic on integer and floating point values.
- There are two
+
operators:- The binary addition operator adds one number to another one. (There is also a binary
+
operator that performs string concatenation. That is described in a separate example.) - The unary plus operator does nothing apart from triggering numeric promotion (see below)
- The binary addition operator adds one number to another one. (There is also a binary
- There are two
-
operators:- The binary subtraction operator subtracts one number from another one.
- The unary minus operator is equivalent to subtracting its operand from zero.
- The binary multiply operator (*) multiplies one number by another.
- The binary divide operator (/) divides one number by another.
- The binary remainder1 operator (%) calculates the remainder when one number is divided by another.
1 - This is often referred to as the "modulus" operator, but "remainder" is the term that is used by the JLS.
Operand and result types, and numeric promotion
The operators require numeric operands and produce numeric results. The operand types can be any primitive numeric type (i.e.
byte
,short
,char
,int
,long
,float
ordouble
) or any numeric wrapper type define injava.lang
; i.e. (Byte
,Character
,Short
,Integer
,Long
,Float
orDouble
.The result type is determined base on the types of the operand or operands, as follows:
- If either of the operands is a
double
orDouble
, then the result type isdouble
. - Otherwise, if either of the operands is a
float
orFloat
, then the result type isfloat
. - Otherwise, if either of the operands is a
long
orLong
, then the result type islong
. - Otherwise, the result type is
int
. This coversbyte
,short
andchar
operands as well as `int.
The result type of the operation determines how the arithmetic operation is performed, and how the operands are handled
- If the result type is
double
, the operands are promoted todouble
, and the operation is performed using 64-bit (double precision binary) IEE 754 floating point arithmetic. - If the result type is
float
, the operands are promoted tofloat
, and the operation is performed using 32-bit (single precision binary) IEE 754 floating point arithmetic. - If the result type is
long
, the operands are promoted tolong
, and the operation is performed using 64-bit signed twos-complement binary integer arithmetic. - If the result type is
int
, the operands are promoted toint
, and the operation is performed using 32-bit signed twos-complement binary integer arithmetic.
Promotion is performed in two stages:
- If the operand type is a wrapper type, the operand value is unboxed to a value of the corresponding primitive type.
- If necessary, the primitive type is promoted to the required type:
- Promotion of integers to
int
orlong
is loss-less. - Promotion of
float
todouble
is loss-less. - Promotion of an integer to a floating point value can lead to loss of precision. The conversion is performed using IEE 768 "round-to-nearest" semantics.
- Promotion of integers to
The meaning of division
The / operator divides the left-hand operand
n
(the dividend) and the right-hand operandd
(the divisor) and produces the resultq
(the quotient).Java integer division rounds towards zero. The JLS Section 15.17.2 specifies the behavior of Java integer division as follows:
The quotient produced for operands
n
andd
is an integer valueq
whose magnitude is as large as possible while satisfying|d ⋅ q| ≤ |n|
. Moreover,q
is positive when|n| ≥ |d|
andn
andd
have the same sign, butq
is negative when|n| ≥ |d|
andn
andd
have opposite signs.There are a couple of special cases:
- If the
n
isMIN_VALUE
, and the divisor is -1, then integer overflow occurs and the result isMIN_VALUE
. No exception is thrown in this case. - If
d
is 0, then `ArithmeticException is thrown.
Java floating point division has more edge cases to consider. However the basic idea is that the result
q
is the value that is closest to satisfyingd . q = n
.Floating point division will never result in an exception. Instead, operations that divide by zero result in an INF and NaN values; see below.
The meaning of remainder
Unlike C and C++, the remainder operator in Java works with both integer and floating point operations.
For integer cases, the result of
a % b
is defined to be the numberr
such that(a / b) * b + r
is equal toa
, where/
,*
and+
are the appropriate Java integer operators. This applies in all cases except whenb
is zero. That case, remainder results in anArithmeticException
.It follows from the above definition that
a % b
can be negative only ifa
is negative, and it be positive only ifa
is positive. Moreover, the magnitude ofa % b
is always less than the magnitude ofb
.Floating point remainder operation is a generalization of the integer case. The result of
a % b
is the remainderr
is defined by the mathematical relationr = a - (b ⋅ q)
where:q
is an integer,- it is negative only if
a / b
is negative an positive only ifa / b
is positive, and - its magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of
a
andb
.
Floating point remainder can produce
INF
andNaN
values in edge-cases such as whenb
is zero; see below. It will not throw an exception.Important note:
The result of a floating-point remainder operation as computed by
%
is not the same as that produced by the remainder operation defined by IEEE 754. The IEEE 754 remainder may be computed using theMath.IEEEremainder
library method.Integer Overflow
Java 32 and 64 bit integer values are signed and use twos-complement binary representation. For example, the range of numbers representable as (32 bit)
int
-231 through +231 - 1.When you add, subtract or multiple two N bit integers (N == 32 or 64), the result of the operation may be too large to represent as an N bit integer. In this case, the operation leads to integer overflow, and the result can be computed as follows:
- The mathematical operation is performed to give a intermediate two's-complement representation of the entire number. This representation will be larger than N bits.
- The bottom 32 or 64 bits of the intermediate representation are used as the result.
Here are some examples using 32 bit integers:
Operation (Hex) Intermediate (Hex) Result (Hex) 230 + 230 0x4000 + 0x4000 231 0x00008000 -231 0x8000 -231 - 1 0x8000 - 0x40001 -231 - 1 0xFFFF7FFF 231 - 1 0x7FFF It should be noted that integer overflow does not result in exceptions under any circumstances.
Floating point INF and NAN values
Java uses IEE 754 floating point representations for
float
anddouble
. These representations have some special values for representing values that fall outside of the domain of Real numbers:- The "infinite" or INF values denote numbers that are too large. The
+INF
value denote numbers that are too large and positive. The-INF
value denote numbers that are too large and negative. - The "indefinite" / "not a number" or NaN denote values resulting from meaningless operations.
The INF values are produced by floating operations that cause overflow, or by division by zero.
The NaN values are produced by dividing zero by zero, or computing zero remainder zero.
Surprisingly, it is possible perform arithmetic using INF and NaN operands without triggering exceptions. For example:
- Adding +INF and a finite value gives +INF.
- Adding +INF and +INF gives +INF.
- Adding +INF and -INF gives NaN.
- Dividing by INF gives either +0.0 or -0.0.
- All operations with one or more NaN operands give NaN.
For full details, please refer to the relevant subsections of JLS 15. Note that this is largely "academic". For typical calculations, an
INF
orNaN
means that something has gone wrong; e.g. you have incomplete or incorrect input data, or the calculation has been programmer incorrectly. - There are two
-
The left hand operand for these operators must be a either a non-final variable or an element of an array. The right hand operand must be assignment compatible with the left hand operand. This means that either the types must be the same, or the right operand type must be convertible to the left operands type by a combination of boxing, unboxing or widening. (For complete details refer to JLS 5.2.)
The precise meaning of the "operation and assign" operators is specified by JLS 15.26.2 as:
A compound assignment expression of the form
E1 op= E2
is equivalent toE1 = (T) ((E1) op (E2))
, whereT
is the type ofE1
, except thatE1
is evaluated only once.Note that there is an implicit type-cast before the final assignment.
1.
=
The simple assignment operator: assigns the value of the right hand operand to the left hand operand.
Example:
c = a + b
will add the value ofa + b
to the value ofc
and assign it toc
2.
+=
The "add and assign" operator: adds the value of right hand operand to the value of the left hand operand and assigns the result to left hand operand. If the left hand operand has type
String
, then this a "concatenate and assign" operator.Example:
c += a
is roughly the same asc = c + a
3.
-=
The "subtract and assign" operator: subtracts the value of the right operand from the value of the left hand operand and assign the result to left hand operand.
Example:
c -= a
is roughly the same asc = c - a
4.
*=
The "multiply and assign" operator: multiplies the value of the right hand operand by the value of the left hand operand and assign the result to left hand operand. .
Example:
c *= a
is roughly the same asc = c * a
5.
/=
The "divide and assign" operator: divides the value of the right hand operand by the value of the left hand operand and assign the result to left hand operand.
Example:
c /*= a
is roughly the same asc = c / a
6.
%=
The "modulus and assign" operator: calculates the modulus of the value of the right hand operand by the value of the left hand operand and assign the result to left hand operand.
Example:
c %*= a
is roughly the same asc = c % a
7.
<<=
The "left shift and assign" operator.
Example:
c <<= 2
is roughly the same asc = c << 2
8.
>>=
The "arithmetic right shift and assign" operator.
Example:
c >>= 2
is roughly the same asc = c >> 2
9.
>>>=
The "logical right shift and assign" operator.
Example:
c >>>= 2
is roughly the same asc = c >>> 2
10.
&=
The "bitwise and and assign" operator.
Example:
c &= 2
is roughly the same asc = c & 2
11.
|=
The "bitwise or and assign" operator.
Example:
c |= 2
is roughly the same asc = c | 2
12.
^=
The "bitwise exclusive or and assign" operator.
Example:
c ^= 2
is roughly the same asc = c ^ 2
-
The Java language provides three operator for performing bitwise shifting on 32 and 64 bit integer values. These are all binary operators with the first operand being the value to be shifted, and the second operand saying how far to shift.
-
The
<<
or left shift operator shifts the value given by the first operand leftwards by the number of bit positions given by the second operand. The empty positions at the right end are filled with zeros. -
The '>>' or arithmetic shift operator shifts the value given by the first operand rightwards by the number of bit positions given by the second operand. The empty positions at the left end are filled by copying the left-most bit. This process is known as sign extension.
-
The '>>>' or logical right shift operator shifts the value given by the first operand rightwards by the number of bit positions given by the second operand. The empty positions at the left end are filled with zeros.
Notes:
-
These operators require an
int
orlong
value as the first operand, and produce a value with the same type as the first operand. (You will need to use an explicit type cast when assigning the result of a shift to abyte
,short
orchar
variable.) -
If you use a shift operator with a first operand that is a
byte
,char
orshort
, it is promoted to anint
and the operation produces anint
.) -
The second operand is reduced modulo the number of bits of the operation to give the amount of the shift. For more about the mod mathematical concept, see Modulus examples.
-
The bits that are shifted off the left or right end by the operation are discarded. (Java does not provide a primitive "rotate" operator.)
-
The arithmetic shift operator is equivalent dividing a (two's complement) number by a power of 2.
-
The left shift operator is equivalent multiplying a (two's complement) number by a power of 2.
The following table will help you see the effects of the three shift operators. (The numbers have been expressed in binary notation to aid vizualization.)
Operand1 Operand2 <<
>>
>>>
0b0000000000001011 0 0b0000000000001011 0b0000000000001011 0b0000000000001011 0b0000000000001011 1 0b0000000000010110 0b0000000000000101 0b0000000000000101 0b0000000000001011 2 0b0000000000101100 0b0000000000000010 0b0000000000000010 0b0000000000001011 28 0b1011000000000000 0b0000000000000000 0b0000000000000000 0b0000000000001011 31 0b1000000000000000 0b0000000000000000 0b0000000000000000 0b0000000000001011 32 0b0000000000001011 0b0000000000001011 0b0000000000001011 ... ... ... ... ... 0b1000000000001011 0 0b1000000000001011 0b1000000000001011 0b1000000000001011 0b1000000000001011 1 0b0000000000010110 0b1100000000000101 0b0100000000000101 0b1000000000001011 2 0b0000000000101100 0b1110000000000010 0b00100000000000100 0b1000000000001011 31 0b1000000000000000 0b1111111111111111 0b0000000000000001 There examples of the user of shift operators in Bit manipulation
-
-
The
==
and!=
operators are binary operators that evaluate totrue
orfalse
depending on whether the operands are equal. The==
operator givestrue
if the operands are equal andfalse
otherwise. The!=
operator givesfalse
if the operands are equal andtrue
otherwise.These operators can be used operands with primitive and reference types, but the behavior is significantly different. According to the JLS, there are actually three distinct sets of these operators:
- The Boolean
==
and!=
operators. - The Numeric
==
and!=
operators. - The Reference
==
and!=
operators.
However, in all cases, the result type of the
==
and!=
operators isboolean
.The Numeric
==
and!=
operatorsWhen one (or both) of the operands of an
==
or!=
operator is a primitive numeric type (byte
,short
,char
,int,
long
,float
ordouble
), the operator is a numeric comparison. The second operand must be either a primitive numeric type, or a boxed numeric type.The behavior other numeric operators is as follows:
- If one of the operands is a boxed type, it is unboxed.
- If either of the operands now a
byte
,short
orchar
, it is promoted to anint
. - If the types of the operands are not the same, then the operand with the "smaller" type is promoted to the "larger" type.
- The comparison is then carried out as follows:
- If the promoted operands are
int
orlong
then the values are tested to see if they are identical. - If the promoted operands are
float
ordouble
then:- the two versions of zero (
+0.0
and-0.0
) are treated as equal - a
NaN
value is treated as not equals to anything, and - other values are equal if their IEEE 754 representations are identical.
- the two versions of zero (
- If the promoted operands are
Note: you need to be careful when using
==
and!=
to compare floating point values.The Boolean
==
and!=
operatorsIf both operands are
boolean
, or one isboolean
and the other isBoolean
, these operators the Boolean==
and!=
operators. The behavior is as follows:- If one of the operands is a
Boolean
, it is unboxed. - The unboxed operands are tested and the boolean result is calculated according to the following truth table
A B A == B A != B false false true false false true false true true false false true true true true false There are two "pitfalls" that make it advisable to use
==
and!=
sparingly with truth values:-
If you use
==
or!=
to compare twoBoolean
objects, then the Reference operators are used. This may give an unexpected result; see Pitfall: using == to compare primitive wrappers objects such as Integer -
The
==
operator can easily be mistyped as=
. For most operand types, this mistake leads to a compilation error. However, forboolean
andBoolean
operands the mistake leads to incorrect runtime behavior; see Pitfall - Using '==' to test a boolean
The Reference
==
and!=
operatorsIf both operands are object references, the
==
and!=
operators test if the two operands refer to the same object. This often not what you want. To test if two objects are equal by value, the.equals()
method should be used instead.String s1 = "We are equal"; String s2 = new String("We are equal"); s1.equals(s2); // true // WARNING - don't use == or != with String values s1 == s2; // false
Warning: using
==
and!=
to compareString
values is incorrect in most cases; see http://stackoverflow.com/documentation/java/4388/java-pitfalls/16290/using-to-compare-strings . A similar problem applies to primitive wrapper types; see http://stackoverflow.com/documentation/java/4388/java-pitfalls/8996/using-to-compare-primitive-wrappers-objects-such-as-integer .About the NaN edge-cases
JLS 15.21.1 states the following:
If either operand is
NaN
, then the result of==
isfalse
but the result of!=
istrue
. Indeed, the testx != x
istrue
if and only if the value ofx
isNaN
.This behavior is (to most programmers) unexpected. If you test if a
NaN
value is equal to itself, the answer is "No it isn't!". In other words,==
is not reflexive forNaN
values.However, this is not a Java "oddity", this behavior is specified in the IEEE 754 floating-point standards, and you will find that it is implemented by most modern programming languages. (For more information, see http://stackoverflow.com/a/1573715/139985 ... noting that this is written by someone who was "in the room when the decisions were made"!)
- The Boolean
-
From Java 8 onwards, the Lambda operator (
->
) is the operator used to introduce a Lambda Expression. There are two common syntaxes, as illustrated by these examples:Java SE 8a -> a + 1 // a lambda that adds one to its argument a -> { return a + 1; } // an equivalent lambda using a block.
A lambda expression defines an anonymous function, or more correctly an instance of an anonymous class that implements a functional interface.
(This example is included here for completeness. Refer to the Lambda Expressions topic for the full treatment.)
Topic Outline
Introduction
- Increment/Decrement Operators (++/--)
- Conditional Operator (? :)
- Integer Bitwise Operators (~, &, |, ^)
- Operator Precedence and Parentheses
- String Concatenation Operator (+)
- Instanceof Operator
- Regular and short-circuit logical operators ( !, &, |, ^, && and || )
- The Arithmetic Operators (+, -, *, /, %)
- The Assignment Operators (=, +=, -=, *=, /=, %=, <<=, >>= , >>>=, &=, |= and ^=)
- The Shift Operators (<<, >> and >>>)
- The Equality Operators (==, !=)
- The Lambda operator ( -> )
Syntax
Sign up or log in
Save edit as a guest
Join Stack Overflow
Using Google
Using Facebook
Using Email and Password
We recognize you from another Stack Exchange Network site!
Join and Save Draft