Java: why do I receive the error message "Type mismatch: cannot convert int to byte"

24,218

Solution 1

Although the arithmetic operators are defined to operate on any numeric type, according the Java language specification (5.6.2 Binary Numeric Promotion), operands of type byte and short are automatically promoted to int before being handed to the operators.

To perform arithmetic operations on variables of type byte or short, you must enclose the expression in parentheses (inside of which operations will be carried out as type int), and then cast the result back to the desired type.

byte a = 23;
byte b = 34;
byte c = (byte) (a + b);

Here's a follow-on question to the real Java gurus: why? The types byte and short are perfectly fine numeric types. Why does Java not allow direct arithmetic operations on these types? (The answer is not "loss of precision", as there is no apparent reason to convert to int in the first place.)

Update: jrudolph suggests that this behavior is based on the operations available in the JVM, specifically, that only full- and double-word operators are implemented. Hence, to operator on bytes and shorts, they must be converted to int.

Solution 2

The answer to your follow-up question is here:

operands of type byte and short are automatically promoted to int before being handed to the operators

So, in your example, a and b are both converted to an int before being handed to the + operator. The result of adding two ints together is also an int. Trying to then assign that int to a byte value causes the error because there is a potential loss of precision. By explicitly casting the result you are telling the compiler "I know what I am doing".

Solution 3

I think, the matter is, that the JVM supports only two types of stack values: word sized and double word sized.

Then they probably decided that they would need only one operation that works on word sized integers on the stack. So there's only iadd, imul and so on at bytecode level (and no operators for bytes and shorts).

So you get an int value as the result of these operations which Java can't safely convert back to the smaller byte and short data types. So they force you to cast to narrow the value back down to byte/short.

But in the end you are right: This behaviour is not consistent to the behaviour of ints, for example. You can without problem add two ints and get no error if the result overflows.

Solution 4

The Java language always promotes arguments of arithmetic operators to int, long, float or double. So take the expression:

a + b

where a and b are of type byte. This is shorthand for:

(int)a + (int)b

This expression is of type int. It clearly makes sense to give an error when assigning an int value to a byte variable.

Why would the language be defined in this way? Suppose a was 60 and b was 70, then a+b is -126 - integer overflow. As part of a more complicated expression that was expected to result in an int, this may become a difficult bug. Restrict use of byte and short to array storage, constants for file formats/network protocols and puzzlers.

There is an interesting recording from JavaPolis 2007. James Gosling is giving an example about how complicated unsigned arithmetic is (and why it isn't in Java). Josh Bloch points out that his example gives the wrong example under normal signed arithmetic too. For understandable arithmetic, we need arbitrary precision.

Share:
24,218
Brad Richards
Author by

Brad Richards

Updated on July 05, 2022

Comments

  • Brad Richards
    Brad Richards almost 2 years

    If you declare variables of type byte or short and attempt to perform arithmetic operations on these, you receive the error "Type mismatch: cannot convert int to short" (or correspondingly "Type mismatch: cannot convert int to byte").

    byte a = 23;
    byte b = 34;
    byte c = a + b;
    

    In this example, the compile error is on the third line.

  • bestsss
    bestsss about 13 years
    since i found that - the operations are carried out in the CPU registers, but yes they are aligned 32bits. and you cant perform the + operator on chars either
  • user12208242
    user12208242 over 3 years
    byte c = (byte)(a + b); after conversion, this expression will look like this byte c = 57 where 57 is of type byte. But then, as the numeric promotion states that all byte, short and char literals are converted to int, this byte 57 would be promoted to int 57. So in this sense, the compiler should still give an error but it doesn't. Why?