Operators are used to perform mathematical & logical operations. Operators supported by **Java** can be categorized into
arithmetic, logical, relational, bitwise (used for bit manipulation) and some special operators. Let's see how these
operators are used in programming.

**Arithmetic Operators**

**Arithmetic Operators** supported by **Java** are **ADD ( + ), SUBTRACT ( - ), MULTIPLY ( * ), DIVIDE ( / ), MODULO ( % ), INCREMENT ( ++ ) and
DECREMENT ( -- )**.

The behaviour of

Let's look at the following program to see arithmetic operators in action :

*/*
* This program demonstrates the use of arithmetic operators
*/*
**public class** Arithmetic {
**public static void** main(String args[]) {
**int** a = 5, b = 2;
**int** x, y, z, r, s, u, v;
x = a + b; *// addition ( Value of a+b is assigned to x )*
y = a - b; *// subtraction*
z = a * b; *// multiplication*
r = a / b; *// division*
s = a % b; *// modulo*
System.out.println(" Sum of " + a + " and " + b + " is " + x);
System.out.println(" Difference of " + a + " and "+ b + " is " + y);
System.out.println(" Product of " + a + " and "+ b + " is " + z);
System.out.println(" Division of " + a + " by "+ b + " is " + r);
System.out.println(" Modulo of " + a + " by "+ b + " is " + s);
System.out.println(" Incrementing a " + (++a));
System.out.println(" Decrementing b " + (--b));
}
}

Please note that some of the expressions in which a variable is present in both sides can be written as :

Expression | is Equivalent to |

X = X + Y | X += Y |

X = X - Y | X -= Y |

X = X * Y | X *= Y |

X = X / Y | X /= Y |

X = X % Y | X %= Y |

**Logical Operators**

**Logical Operators** supported by **Java** are **AND ( && )**, **OR ( || )** and **NOT ( ! )**.

Consider two operands **A** and **B**.

**A && B** evaluates to **True** only if both **A** and **B** are **True**.

**A || B** evaluates to **True** if any of the two operands is **True**.

**' ! '** operator negates the state of an operand. For e.g, if **A = True**, then **!A = False**.

Note that any **non-zero** value is considered **True** and **zero** is considered **False**.

Following program shows logical operators in action :

*/*
* This program demonstrates the use of logical operators
*/*
**public class** Logical {
**public static void** main(String args[]) {
**boolean** a = **true**, b = **false**;
**boolean** x, y, z;
x = a && b; *// x = false*
y = a || b; *// y = true*
z = !b; *// z = true*
System.out.println(a + " AND " + b + " = " + x);
System.out.println(a + " OR " + b + " = " + y);
System.out.println("NOT " + b + " = " + z);
}
}

**Relational Operators**

**Relational operators** ( used for comparison operations ) supported by **Java** are **EQUAL ( == ), NOT EQUAL ( != ), GREATER THAN ( > ),
LESS THAN ( < ), GREATER THAN OR EQUAL TO ( >= ) and LESS THAN OR EQUAL TO ( <= )**.

Following program illustrates the behaviour of relational operators :

*/*
* This program demonstrates the use of relational operators
*/*
**public class** Relational {
**public static void** main(String args[]) {
**int** a = 5, b = 2, c = 2;
**boolean** x, y, z, r;
x = ( b == c ); *// x = 1 (true) since b is equal to c*
y = ( a != b ); *// y = 1 (true) since a is not equal to b*
z = ( b < c ); *// z = 0 (false) since b is not less than c*
r = ( b <= c ); *// r = 1 (true) since b is not less but equal to c*
System.out.println(" x : "+ x);
System.out.println(" y : "+ y);
System.out.println(" z : "+ z);
System.out.println(" r : "+ r);
}
}

**Bitwise Operators**

**Bitwise Operators** ( used for bit manipulation ) supported by **Java** are **BITWISE AND ( & ), BITWISE OR ( | ), BITWISE XOR ( ^ ), BITWISE NOT ( ~ ), LEFT SHIFT ( << ), RIGHT SHIFT ( >> )**
and **RIGHT SHIFT WITH ZERO FILL ( >>> )**. These operators operate at **bit** level.

Consider two bits **bit1** and **bit2**.

**bit1 & bit2** evaluates to **True** if and only if both **bit1** and **bit2** are **True**.

**bit1 | bit2** evaluates to **True** if any of the two bits is **True**.

**bit1 ^ bit2** evaluates to **True** if and only if one of the bits is **True**.

**~** operator toggles a bit. If **bit1 = True**, the **~bit1 = False.**

' **A << 2** ' left shifts the bits of a number (A) by 2 positions.

' **A >> 1** ' right shifts the bits of a number (A) by 1 position.

' **A >>> 1** ' right shifts the bits of a number (A) by 1 position and shifted values are filled up with zeroes.

**Difference between >> and >>> operators**

There is no difference between the two operators when we are dealing with positive integers. The difference is observed in case of negative integers.
The Most Significant Bit (** MSB **) or the leftmost bit is **1** in case of negative integers ( i.e MSB is the sign bit ). Now, when we use ** >> ** on a negative
integer, the **sign bit** is not shifted but if we use ** >>> ** operator, the **sign bit** is also shifted along with other
bits and the position of sign bit is filled with **0** along with other shifted values.

Suppose **A = 7** and **B = 19**. In binary format : **A = 00000111** and **B = 00010011**

Following table shows how bitwise operators do bit manipulation :

Binary |
||||||||

A | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |

B | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 |

A & B | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |

A | B | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |

A ^ B | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |

~A | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |

A << 2 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |

A >> 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |

Following program demonstrate the behaviour of bitwise operators :

*/*
* This program demonstrates the use of bitwise operators
*/*
**public class** Bitwise {
**public static void** main(String args[]) {
**int** a = 7, b = 19, c = -7;
**int** x, y, z, r, s, t, p, q;
x = a & b; */* 7 & 19 = (00000111 & 00010011) = 00000011 = 3 */*
y = a | b; */* 7 | 19 = (00000111 | 00010011) = 00010111 = 23 */*
z = a ^ b; */* 7 ^ 19 = (00000111 ^ 00010011) = 00010100 = 20 */*
r = a << 2; */* 7 << 2 = (00000111 << 2) = 00011100 = 28 */*
s = a >> 1; */* 7 >> 1 = (00000111 >> 1) = 00000011 = 3 */*
p = c >> 2;
q = c >>> 2;
System.out.println(a + " & " + b + " = " + x);
System.out.println(a + " | " + b + " = " + y);
System.out.println(a + " ^ " + b + " = " + z);
System.out.println(a + " << " + 2 + " = " + r);
System.out.println(a + " >> " + 1 + " = " + s);
System.out.println(c + " >> " + 2 + " = " + p);
System.out.println(c + " >>> " + 2 + " = " + q);
}
}

Note that in the above program, there is no demonstration of **NOT ( ~ )** operator since the result would be unexpected and will confuse you. You might have noticed that all decimal numbers are represented using 8 bits

( 1 Octet ) but in the system memory it is stored as a sequence of multiple octets (4 in case of 32 bit systems). In our case, other 3 octets would be all **0**s. But **NOT** operation would toggle all those **0**s to **1**s which would result into a very high value ( outside the range of **int** ). As a result, some unexpected value would be displayed.

**Special Operators**

instanceof | This operator is applicable to objects only. It checks whether an object is of particular class type. |

Condition | Conditional Operator returns a value depending on a condition. Syntax : ( Condition ? a : b ). If condition is true, a is returned else b
is returned. |

Assignment | It is used to assign one value to other in an expression. In the expression c = a + b, value of ( a + b ) is assigned to c. |

Following program illustrates the use of **conditional** operator :

*/*
* This program demonstrates the use of conditional operator
*/*
**public class** Conditional {
**public static void** main(String args[]) {
**int** a = 5, b = 2;
*/* if a > b, then value in 'a' assigned to 'c'
else value in 'b' is assigned to 'a' */*
**int** c = ( a > b ) ? a : b; *// c holds greater of a and b*
System.out.println("Greater of " + a + " and " + b + " is " + c);
}
}

Following program illustrates the use **instanceof** operator :

*/*
* This program demonstrates the use of instanceOf operator
*/*
**public class** Instance {
**public static void** main(String args[]) {
Instance inst = **new** Instance(); *//create an object of Instance type*
String str = **new** String("abc"); *//create an object/variable of String type*
**boolean** result1 = inst **instanceof** Instance; *// result1 = true*
**boolean** result2 = str **instanceof** String; *// result2 = true*
System.out.println("result1 : " + result1);
System.out.println("result2 : " + result2);
}
}

The **instanceof** operator is not used much and the above program doesn't reflect a practical use case. It can be useful in knowing
the actual class of an object when we are using **inheritance**, a feature which we will discuss later in the tutorial.

**Operator Precedence & Associativity**

**Precedence** of operators determines the order of evaluation of expression consisting of multiple operators.

Higher precedence operators will
be evaluated first. **Associativity** determines whether an expression is evaluated **left to right** or **right to left**. Consider the expressions below :

x = 2 + 3 * 2 => x = 2 + 6 => x = 8 ( '*' has higher precedence than '+' ) |

y = 2 * 3 / 2 => y = 6 / 2 => y = 3 ( '*' and '/' has same precedence but associativity is left to right ) |

z = 3 / 2 * 2 => z = 1 * 2 => z = 2 ( '*' and '/' has same precedence but associativity is left to right ) |

Following table shows the precedence and associativity of the C++ operators ( Operator precedence decreases as we move downwards ) :

Operators | Precedence |

Postfix ( ++, -- ) | Left to Right |

Unary ( +, -, !, ~), Prefix ( ++, -- ) | Right to Left |

*, /, % | Left to Right |

Additive ( +, - ) | Left to Right |

Left and Right Shift ( <<, >>, >>> ) | Left to Right |

Relational ( <, <=, >, >= ) | Left to Right |

Equality ( ==, != ) | Left to Right |

Bitwise AND ( & ) | Left to Right |

Bitwise XOR ( ^ ) | Left to Right |

Bitwise OR ( | ) | Left to Right |

Logical AND ( && ) | Left to Right |

Logical OR ( || ) | Left to Right |

Conditional ( Condition ? x : y ) | Right to Left |

Assignment ( = ) | Right to Left |

*Note : **Unary** operators have single operand

**Postfix and Prefix Operators**

The increment (++) and decrement (--) operators can appear either on left side (prefix) or right side (postfix) of the operand.
Following program demonstrates the behaviour of postfix and prefix operators :

*/*
* This program demonstrates the use of postfix and prefix operator
*/*
**public class** PostfixPrefix {
**public static void** main(String args[]) {
**int** a = 5, b = 2;
**int** c = 7, d = 3;
**int** x, y, r, s;
x = ++a; *// first increment a, then assign its value to x*
System.out.println(" x : " + x + ", a : " + a); *// displays x : 6, a : 6*
y = b++; *// first assign value of b to y, then increment b*
System.out.println(" y : " + y + ", b : " + b); *// displays y : 2, b : 3*
r = --c; *// first decrement c, then assign its value to r*
s = d--; *// first assign value of d to s, then decrement d*
System.out.println(" r : " + r + ", c : " + c); *// displays r : 6, c : 6*
System.out.println(" s : " + s + ", d : " + d); *// displays s : 3, c : 2*
}
}

**Typecasting**

Sometimes it is required to explicitly convert a variable from one data type to another. This concept is known as **typecasting**.
Following program will make it clear.

*/*
* This program demonstrates typecasting
*/*
**public class** Typecast {
**public static void** main(String args[]) {
**int** a = 7, b = 3;
**float** x, y, z;
x = a / b; */* x = 2.0 */*
y = (**float**)a / b; */* variable 'a' is typecasted [ y = 2.333333 ] */*
z = (**float**)(a / b); */* (a / b) is typecasted [ z = 2.0 ] */*
System.out.println("x = " + x + "\ny = " + y + "\nz = " + z);
}
}

In the above program, both **a** and **b** are integers. Now, **( a / b ) = ( 7 / 3 )= 2** . Now, since **x**
is a float type variable, so **x** stores **2.000000** . In case of **y** , variable **a** is converted to float and thus the expression
is evaluated as **y = (float)a / b = ( 7.000000 / 3 ) = 2.333333**. In case of **z**, the value of **( a / b )**
is converted to float and the expression is evaluated as **y = (float) ( a / b ) = float ( 7 / 3 ) = float ( 2 ) = 2.000000**.

**Automatic Type Conversion**

In **Java**, we can mix variables and constants of different data types in an expression. During evaluation, operands of lower type
is automatically converted to higher type. For e.g, If an expression consists of byte, int and float operands, the result is always
promoted to **float**.