Java Tutorials : Java Operators Explained
3. Shift operators - <<, >>, >>>
- << Performs a signed left shift. 0 bits are brought in from the right. Sign bit (MSB) is preserved. Value becomes old value * 2 ^ x where x is no of bits shifted.
- >> Performs a signed right shift. Sign bit is brought in from the left. (0 if positive, 1 if negative. Value becomes old value / 2 ^ x where x is no of bits shifted. Also called arithmetic right shift.
- >>> Performs an unsigned logical right shift. 0 bits are brought in from the left. This operator exists since Java doesn't provide an unsigned data type (except char). >>> Changes the sign of a negative number to be positive. So don't use it with negative numbers, if you want to preserve the sign. Also don't use it with types smaller than int. (Since types smaller than int are promoted to an int before any shift operation and the result is cast down again, so the end result is unpredictable.)
- Shift operators can be applied to only integral types.
- -1 >> 1 is -1, not 0. This differs from simple division by 2. We can think of it as shift operation rounding down.
- 1 << 31 will become the minimum value that an int can represent. (Value becomes negative, after this operation, if you do a signed right shift sign bit is brought in from the left and the value remains negative.)
- Negative numbers are represented in two's complement notation. (Take one's complement and add 1 to get two's complement)
- Shift operators never shift more than the number of bits the type of result can have. (i.e. int 32, long 64) RHS operand is reduced to RHS % x where x is no of bits in type of result.
4. Comparison operators :all return Boolean type.
4.1 Ordinal comparisons - <, <=, > , >=
- Only operate on numeric types. Test the relative value of the numeric operands.
- Arithmetic promotions apply. char can be compared to float.
4.2 Object type comparison - instanceof
- Tests the class of an object at runtime. Checking is done at compile and runtime same as the cast operator.
- Returns true if the object denoted by LHS reference can be cast to RHS type.
- LHS should be an object reference expression, variable or an array reference.
- RHS should be a class (abstract classes are fine), an interface or an array type, castable to LHS object reference. Compiler error if LHS & RHS are unrelated.
- Can't use java.lang.Class or its String name as RHS.
- Returns true if LHS is a class or subclass of RHS class
- Returns true if LHS implements RHS interface.
- Returns true if LHS is an array reference and of type RHS.
- x instanceof Component-legal.
- x instanceof  - illegal. Can't test for 'any array of any type'
- Returns false if LHS is null, no exceptions are thrown.
- If x instanceof Y is not allowed by compiler, then Y y = (Y) x is not a valid cast expression. If x instanceof Y is allowed and returns false, the above cast is valid but throws a ClassCastException at runtime. If x instanceof Y returns true, the above cast is valid and runs fine.
4.3 Equality comparisons - ==, !=
- For primitives it's a straightforward value comparison. (Promotions apply)
- For object references, this doesn't make much sense. Use equals method for meaningful comparisons. (Make sure that the class implements equals in a meaningful way, like for X.equals(Y) to be true, Y instance of X must be true as well)
- For String literals, == will return true, this is because of compiler optimization.