This Java article is to discuss about the numeric promotion that happens when using operators. Similar to the last Java puzzle on floating point precision, this article will also make raise some eyebrows. Last week a regular reader of Javapapers Palani Kumar wrote to me and asked a question,
“Why I cannot add two byte and short data type in Java?” Thanks Palani, this article is the response to your question :-)
Can you guess the output of the following Java program?
public class NumericPromotion { public static void main(String... args){ //part 1 final byte a = 1; final byte b = 2; byte c = a + b; System.out.println(c); //part 2 byte i = 1; byte j = 2; byte k = i + j; System.out.println(k); } }
There are two parts to it. Absolutely no problem with the first part. Two Java final byte variables are created. Then they are added into a byte variable. This addition statement gets processed at compile time and since both its operands are final variables, the ‘byte c’ is instantiated and the constant value ‘3’ is assigned.
So what we have here is a narrowing conversion and it is possible, if all the operands are constant values in an expression. As per Java Language Specification (JLS),
In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int: – A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable
Now to part 2. Here we got problem! We get the following error on compilation of the above Java program.
NumericPromotion.java:10: error: possible loss of precision byte k = i + j; ^ required: byte found: int 1 error
The statement where the Java compiler complains about is a normal arithmetic statement. We are adding two byte variables and assigning it to another byte variable. Whats wrong with this? The error says, “required: byte and found: int”. How come, it found ‘int’? We have never declared anything as int in this program.
Here is what happens. There is no addition operator for byte. This addition operator used here promotes its operands to ‘int’ automatically. After promoted it becomes addition of two int values and so the result is an int value. Now the issue is, this result int value cannot be assigned to a byte variable k.
Narrowing conversion is not done automatically by the Java runtime. We need to explicitly cast the value to byte. If you want to know about narrowing conversion and cast in Java, please go read this previous tutorial. It is a comprehensive tutorial and I seriously recommend it to you as I am sure you will find something new there. As per JLS,
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, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:
- If any of the operands is of a reference type, unboxing conversion
(§5.1.8) is performed. Then:- If either operand is of type double, the other is converted to double.
- Otherwise, if either operand is of type float, the other is converted to
float.- Otherwise, if either operand is of type long, the other is converted to
long.- Otherwise, both operands are converted to type int.
Comments are closed for "Java Numeric Promotion".
Hi Joe,
so second part would be?
byte i = 1;
byte j = 2;
byte k = (byte)(i + j);
System.out.println(k);
Thanks for great blog.
it was nice……thank u
Yes that’s right kciejek. Thanks.
before reading thru this tutorial I just thought that it’s just the way it is, but I didn’t know about the “final bytes”
Thanks Joe
Welcom Pratik.
Good learning … Thanks joe