Commonly used operators :

Following are some of the commonly used JavaTM technology operators – Multiplication (*), Addition (+), Subtraction (-), logical and (&&) Conditional Operator ?:, Assignment (=), left shift (<<), right shift (>> and >>>), Equality comparison (==), Non-equality comparison (!=).

Conversion rules in Assignments :

In the description below, I am giving basic conversion rules for assignment when source and destination are of different types.

  1. If source and destination are of the same type, assignment happens without any issues.
  2. If source is of smaller size than destination but source and destination are of compatible types, then no casting is required. Implicit widening takes place in this case. An example is assigning an int to a long.
  3. If source and destination are of compatible types, but source is of larger size than destination, explicit casting is required. In this case, if no casting is provided then the program does not compile.

Floating point numbers :

Decimal numbers (for example 1.3) are of type double by default. To make them of type float they must be followed by F (say, 1.3F).

The equality operator :

The equality operator (==) when applied to objects return true if two objects have same reference value, false otherwise. The example below illustrates this —

 String str1 = "first string";
    String str2 = new String("first string");
    String str3 = "first string";
    boolean test1 = (str1 == str2);
    boolean test2 = (str1 == str3);

In the example above, test1 is set to false because str1 and str2 point to different references. As str1 and str3 point to the same reference, test2 gets set to true. When a string is initialized without using the new operator, and with an existing string, then the new string also points to the first string’s location. So in the example above, str1 and str3 point to the same pool of memory and hence test2 gets set to true. The string str2 on the other hand is created using the new operator and hence points to a different block of memory. Hence test1 gets set to false.

The conditional operators && and ||

Operator && returns true if both operands are true, false otherwise. Operator || returns false if both operands are false, true otherwise. The important thing to note about these operators is that they are short-circuited. This means that the left operand is evaluated before the right operator. If the result of the operation can be evaluated after computing the left operand, then the right side is not computed. In this respect these operators are different from their bit-wise counterparts – bit-wise and (&), and bit-wise or (|). The bit-wise operators are not short-circuited. This means both the operands of bit-wise operator are always evaluated independent of result of evaluations.

Storing integral types :

All the integer types in Java technology are internally stored in two’s complement. In two’s complement, positive numbers have their corresponding binary representation. Two’s complement representation of negative numbers is generated using the following three step process –

  • First get the binary representation of the number.
  • Then interchange zeros and ones in the binary representation.
  • Finally add one to the result. So for example two’s complement of -18 would be (assuming one byte representation) –
    • Converting 18 to binary — 0001 0010
    • Interchanging 0s and 1s — 1110 1101
    • Adding 1 — 1110 1110

So 1110 1110 would be binary representation of -18 using two bytes and using two’s complement representation.

The shift operators :

The shift left operator in Java technology is “<<“. There are two operators for doing the right shift – signed right shift (>>) and zero fill right shift (>>>).The left shift operator fills the right bits by zero. The effect of each left shift is multiplying the number by two. The example below illustrates this –

int i = 13; // i is 00000000 00000000 00000000 0000 1101
i = i << 2; // i is 00000000 00000000 00000000 0011 0100

After this left shift, i becomes 52 which is same as multiplying i by 4

Zero fill shift right is represented by the symbol >>>. This operator fills the leftmost bits by zeros. So the result of applying the operator >>> is always positive. (In two’s complement representation the leftmost bit is the sign bit. If sign bit is zero, the number is positive, negative otherwise.) The example below illustrates applying the operator >>> on a number.

int b = 13; // 00000000 00000000 00000000 0000 1101
b = b >>> 2; // b is now 00000000 00000000 00000000 0000 0011

So the result of doing a zero fill right shift by 2 on 13 is 3. The next example explains the effect of applying the operator >>> on a negative number.

int b = -11; //11111111 11111111 11111111 1111 0101
b = b >>> 2; // b now becomes 00111111 11111111 11111111 1111 1101

So the result of applying zero fill right shift operator with operand two on -11 is 1073741821.

Signed right shift operator (>>) fills the left most bit by the sign bit. The result of applying the signed shift bit has the same sign as the left operand. For positive numbers the signed right shift operator and the zero fill right shift operator both give the same results. For negative numbers, their results are different. The example below illustrates the signed right shift.

int b = -11; // 11111111 11111111 11111111 1111 0101
b = b >> 2; // 11111111 11111111 11111111 1111 1101 (2’s complement of -3)
// Here the sign bit 1 gets filled in the two most significant bits.

The new value of b becomes -3.