Result of applying "+" operator to any combination of variables or constants of any type:
For a + expression with 2 operands of primitive numeric type the result
-------char | |||||
| | |||||
V | |||||
double<------- | float<---------- | long<---------- | int<------------- | short<--------- | byte |
For a + expression with any operand that is not of primitive numeric type :
public class concat{
public static void main(Strng s[]) { String a="da"; int i = 20; String b=a+i; System.out.println(b); //prints "da20" } } |
eg,
byte b = 42;
char c = 'a'; short s = 1024; int i = 50000; float f = 5.67f; double d = .1234; double result = (f * b) + (i / c) - (d * s); System.out.println((f * b) + " + " + (i / c) + " - " + (d * s)); System.out.println("result = " + result); |
another eg,
float f=4.6;//give compilation error
float=4 ;//compiles fine |
another eg,
short s = 8;
int i = 10; float f = 6.5f; doubld d = 10.5; if(++s * i >= f/d) System.out.println("greater"); else System.out.println("smaller"); |
Result of applying "==" operator to any two objects of any
type:
Note: Read also the next objective.
Remember : When the operands on the either side of == is
boolean flag=false;
if(flag=true) System.out.println("true"); else System.out.println("false"); |
This will print "true" because flag is assigned a boolean value and which is what if expects.
but if "=" is used with any other type
String s1="abc";
String s2="abc"; if(s1=s2) System.out.println("equal;"); |
gives a compiler error saying, Incompatible type for if. can't convert java.lang.String to boolean
instanceof operator to operands :
public class myButton extends JButton {
public static void main(String s[]) { JButton b=new JButton("hello"); myButton mb = new myButton(); System.out.println(b instanceof JButton);//true System.out.println(mb instanceof JButton);//true System.out.println(mb instanceof myButton);//true System.out.println(b instanceof myButton);//false |
obviously b and mb are instances of JButton and myButton respectively.
mb instanceof JButton returns true because myButton extends JButton.
Finally, b instanceof myButton prints false because b is not subclass
of myButton.
another eg,
class furniture {
class table extends furniture{} class chair extends furniture{} public class wood { public static void main(String arg[]) { furniture f=new table(); if(f instanceof table) System.out.println("table"); if(f instanceof furniture) System.out.println("furniture"); if(f instanceof chair) System.out.println("chair"); else System.out.println("I am not!"); } } |
output :
table
furniture
I am not!
Remember : instanceof is an operator which is used with superclasses to tell if you have a particular subclass.
String s1 = new String("hi");
String s2 = new String("hi"); System.out.println(s1 == s2); |
The above code will display "false".
because, the == operator performs a shallow comparison. It just checks
to see if two object references are the
same. It doesn't look at the contents to see if the two are essentially
equal. Here s1 and s2 are pointing to two entirely
different objects, so the test has to return false.
However, the foll. code:
String s1 = "hi";
String s2 = "hi"; System.out.println(s1==s2); |
would return true. Because anytime Java encounters a literal String
it gives you a new String and adds it to the
literal pool. In the above code, by the time Java gets to s2, "hi"
already exists as a literal, so it uses the same object
for both object references s1 and s2. So the test has to return true.
String s1 = "abc" + "def";
String s2 = new String(s1); if(s1.equals(s2)) System.out.println("equals"); if(s1==s2) System.out.println("=="); |
output :
equals
So, for String and Boolean, equals() is overridden to provide an equality
test. For any other class that is a direct extension of Object and does
not override equals(), the test will return false.
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean(true); System.out.println (b1==b2); //prints "false"
|
b1 and b2 are different objects but the Boolean class overrides the
equals() test to return true if the two objects being
compared have the same boolean value.
Operator Precedence :
& |
| |
&& |
|| |
Short-Circuit Logical Operators : &&, ||
The Order of Evaluation of Logic Operators :
If you use the || and && forms, rather than the | and &
forms of these operators, Java will not bother to evaluate the right-hand
operand when the outcome of the expression can be determined by the left
operand alone. This is very useful when the right-hand operand depends
on the left one being true or false in order to function properly.
if (denom != 0 && num / denom > 10) |
Since the short-circuit form of AND (&&) is used, there is no risk of causing a run-time exception when denom is zero. If this line of code were written using the single & version of AND, both sides would have to be evaluated, causing a run-time exception when denom is zero.
It is standard practice to use the short-circuit forms of AND and OR in cases involving Boolean logic, leaving the single-character versions exclusively for bitwise operations.
Another eg,
boolean b, c, d;
b = (2 > 3); // b is false c = (3 > 2); // c is true d = b && c; |
When Java evaluates the expression d = b && c, it first checks
whether b is true. Here b is false, so b && c must be false
regardless of whether c is or is not true, so Java doesn't bother checking
the value of c.
|| is logical or. || combines two boolean variables or expressions and
returns a result that is true if either or both of its
operands are true. For instance
boolean b;
b = 3 > 2 || 5 < 7; // b is true b = 2 > 3 || 5 < 7; // b is still true b = 2 > 3 || 5 > 7; // now b is false |
Remember :
|
|
|
&& | op1 && op2 | op1 and op2 are both true, conditionally evaluates op2 |
|| | op1 || op2 | either op1 or op2 is true, conditionally evaluates op2 |
& | op1 & op2 | op1 and op2 are both true, always evaluates op1 and op2 |
| | op1 | op2 | either op1 or op2 is true, always evaluates op1 and op2 |
Bitwise Operators :&, |
& | 0 | 1 |
0 | 0 | 0 |
1 | 0 | 1 |
eg, 12 & 13
00101010 (42)
& 00001111 (15)
--------------
00001010 (10)
--------------
| | 0 | 1 |
0 | 0 | 1 |
1 | 1 | 1 |
00101010 ( 42)
| 00001111 (15)
--------------
00101111 (47)
--------------
The following program demonstrates the bitwise logical operators:
// Demonstrate the bitwise logical operators.
class BitLogic { public static void main(String args[]) { String binary[] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; int a = 3; // 0 + 2 + 1 or 0011 in binary int b = 6; // 4 + 2 + 0 or 0110 in binary int c = a | b; int d = a & b; int e = a ^ b; int f = (~a & b) | (a & ~b); int g = ~a & 0x0f; System.out.println(" a = " + binary[a]);
|
output :
a = 0011
b = 0110
a|b = 0111
a&b = 0010
a^b = 0101
~a&b|a&~b
= 0101
~a = 1100
Boolean Logical Operator :
boolean a = true;
boolean b = false; boolean c = a | b; boolean d = a & b; boolean e = a ^ b; boolean f = (!a & b) | (a & !b); boolean g = !a; System.out.println(" a = " + a); System.out.println(" b = " + b); System.out.println(" a|b = " + c); System.out.println(" a&b = " + d); System.out.println(" a^b = " + e); System.out.println("!a&b|a&!b = " + f); System.out.println(" !a = " + g); |
After running this program, you will see that the same logical rules
apply to boolean values as they did to bits. As you can see
from the following output, the string representation of a Java boolean
value is one of the literal values true or false:
ouput :
a = true
b = false
a|b = true
a&b = false
a^b = true
!a&b|a&!b
= true
!a = false
bitwise shift operators :
The shift operators include left shift << , signed right shift >> , and unsigned right shift >>>.
+ ve >> :
00000000 00000000 00000000 11000000 (192)
00000000 00000000 00000000 01100000 (192 >>
1)
00000000 00000000 00000000 00001100 (192 >>
4)
00000000 00000000 00000000 00000001 (192 >>
7)
-ve >> :
2's compliment :
00000000 00000000 00000000 11000000 (192)
11111111 11111111 11111111 00111111
1
---------------------------------------------
11111111 11111111 11111111 01000000 (-192)
11111111 11111111 11111111 10100000 (-192 >>
1) = -192 / 21 = -96
11111111 11111111 11111111 11110100 (-192 >>
4) = -192 / 24 = -12
11111111 11111111 11111111 11111110 (-192 >>
7) = -192 / 27 = -1
-ve >>> :
11111111 11111111 11111111 01000000 (-192)
00001111 11111111 11111111 11110100 (-192 >>>
4)
00000001 11111111 11111111 11111110 (-192 >>>
7)
+ve << :
00000000 00000000 00000000 11000000 (192)
00000000 00000000 00000001 10000000 (192 <<
1)
00000000 00000000 00001100 00000000 (192 <<
4)
00000000 00000000 01100000 00000000 (192 <<
7)
-ve << :
11111111 11111111 11111111 01000000 (-192)
11111111 11111111 11111110 10000000 (-192 <<
1)
11111111 11111111 11110100 00000000 (-192 <<
4)
11111111 11111111 10100000 00000000 (-192 <<
7)
Remember : In simple division if you divide -1 by 2, the result will be 0. But, the result of arithmetic shift right of -1 right is -1. You can think this as the shift operation rounding down, while the divisions rounds to 0.
Variables of built-in types are passed by value, objects are passed by reference.
public class passRef {
static void passMethod(passRef p) { System.out.println("p inside passMethod() : " + p); } public static void main(String arg[]) { passRef r = new passRef(); System.out.println("r inside main() : " + r); passMethod(r); } } |
output : will look something like this.
r inside main(): passRef@7e56f2e3
p inside passMethodf(): passRef@7e56f2e3
you can see that both p and r refer to the same object.
Passing a handle is the most efficient form of argument passing, but if you don't want to modify the outside object and want changes to affect only a local copy you use "pass by value".
public class passVal{
int i=10; void print(int i) { i=i+5; System.out.println("inside print : " + i); } public static void main(String arg[]) { passVal p = new passVal(); p.print(p.i); System.out.println("inside main : " + p.i); } } |
output :
inside print : 15
inside main : 10
float f;
double d; f = 3.45f; d = Math.cos(f); //passing float to method that expects double |
Remember :