Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is "short thirty = 3 * 10" a legal assignment?

If short is automatically promoted to int in arithmetic operations, then why is:

short thirty = 10 * 3; 

A legal assignment to the short variable thirty?

In turn, this:

short ten = 10; short three = 3; short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED 

as well as this:

int ten = 10; int three = 3; short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED 

does not compile because assigning an int value to a short is not allowed without casting as expected.

Is there something special going on about numerical literals?

like image 725
Ceiling Gecko Avatar asked Aug 25 '15 12:08

Ceiling Gecko


1 Answers

Because the compiler replaces 10*3 with 30 at compile time itself. So,effectively : short thirty = 10 * 3 is calculated at compile time.

Try changing ten and three to final short (making them compile time constants) and see what happens :P

Examine byte-code using javap -v for both verisions (10*3 and final short). You will be able to see that there is little difference.

Ok, So, here is the byte code difference for different cases.

Case -1 :

Java Code : main() { short s = 10*3; }

Byte code :

stack=1, locals=2, args_size=1          0: bipush        30  // directly push 30 into "s"          2: istore_1                3: return    

Case -2 :

public static void main(String arf[])  {    final short s1= 10;    final short s2 = 3;    short s = s1*s2; } 

Byte code :

  stack=1, locals=4, args_size=1          0: bipush        10          2: istore_1                3: iconst_3                4: istore_2                5: bipush        30 // AGAIN, push 30 directly into "s"          7: istore_3                8: return    

Case -3 :

public static void main(String arf[]) throws Exception {      short s1= 10;      short s2 = 3;      int s = s1*s2; } 

Byte-code :

stack=2, locals=4, args_size=1          0: bipush        10  // push constant 10          2: istore_1                3: iconst_3        // use constant 3           4: istore_2                5: iload_1                 6: iload_2                 7: imul                    8: istore_3                9: return  

In the above case, 10 and 3 are taken from the local variables s1 and s2

like image 108
TheLostMind Avatar answered Oct 12 '22 03:10

TheLostMind