4

I have code like this

short a = 1;
short b = 2 ;
short c = a + b; // dosen't compile

What is the reason for compilation failure? x + x always produces Integer or bigger Number, but why?

MariuszS
  • 30,646
  • 12
  • 114
  • 155
  • 7
    Because the language designers decided thusly. Would you like a quote from the JLS with that? – Marko Topolnik Jan 17 '14 at 12:39
  • I have heard that this is NOT specified in JLS. – MariuszS Jan 17 '14 at 12:40
  • 1
    Duplicate of duplicate: http://stackoverflow.com/questions/18100785/short-plus-short-is-an-int and http://stackoverflow.com/questions/1660856/promotion-in-java – Nigel Tufnel Jan 17 '14 at 12:41
  • @MariuszS It is : http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 – Alexis C. Jan 17 '14 at 12:42
  • The important point is : an int can't be cast into a short. Addition of a and b will produce int. Then, since it can't be cast into short will throw compilation error. – The Dark Knight Jan 17 '14 at 12:44
  • *When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type (...) Otherwise, both operands are converted to type int.* – MariuszS Jan 17 '14 at 13:46

1 Answers1

20

None of the binary operators will produce an Integer. However, it will use an int instead of shorter types, byte, short and char If the compiler can inline the value it can cast the value for your. e.g.

final short a = 1;
final short b = 2;
short c = a + b; // does compile, because of constant inlining.

The only operator which produces an Integer is a cast.

Integer i = (Integer) 1;

BTW: On oddity is that Java defines the 32-bit float as being "wider" than the 64-bit long value. This has the downside that float has much less precision. Consider this.

long l = 7777777777777777777L;
l += 0.0f;
System.out.println(l);

prints

7777777579364188160

Even though 0.0F was added to l it was implicitly cast to float (as float is wider) and then cast back (as an operator assignment was used) resulting in a error of ~20 billion.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 3
    +1: Learned something today :) – Martijn Courteaux Jan 17 '14 at 12:43
  • Possibly a dummy question for @PeterLawrey, but what does actually "to inline the value" mean ? – Konstantin Yovkov Jan 17 '14 at 12:49
  • 1
    @kocko `a` and `b` are *compile-time constants* and wherever they are used in the code, their *value* is compiled in. The bytecode contains no trace of the fact that the source code actually had variables holding the values. – Marko Topolnik Jan 17 '14 at 12:51
  • 1
    @kocko it means the compiler puts the value in the code as if you had typed it there i.e. the byte code will read `short c = 3;` This generally doesn't matter much but if you change a constant using reflection it could mean it doesn't change anything. – Peter Lawrey Jan 17 '14 at 12:52
  • 1
    Thank you both for your simple and clear clarifications :) – Konstantin Yovkov Jan 17 '14 at 12:54
  • 1
    Thanks for `final` example :) – MariuszS Jan 17 '14 at 14:41
  • 1
    Of course `float`s are “wider” than `long`s; you can get much larger values in a `float` (all the way up to `+Inf`…). It just has less precision; its a potentially lossy conversion (in _both_ directions). OTOH, everything in `int` fits exactly in a `double`… – Donal Fellows Jan 17 '14 at 21:23