问题
byte a = 1;
byte b = 1;
byte c = a + b;
Throws error: possible loss of precision
byte subt = a_s - a_b;
^
required: byte
found: int
Is this behavior has something to do with jvm or its been defined in java language .
EDIT : And if it is defined in java language then does it because of keeping jvm in mind ?
Means if java supports byte
datatype then why operation on byte
results int
回答1:
if java supports byte datatype then why operation on byte results int
Because that's how the Java Virtual Machine is designed. There is no instruction set to perform operation on a byte type. Rather the instruction set for int
type is used for the operation on boolean
, byte
, char
, and short
types.
From JVM Spec - Section 2.11.1:
A compiler encodes loads of literal values of types
byte
andshort
using Java Virtual Machine instructions that sign-extend those values to values of typeint
at compile-time or run-time. Loads of literal values of typesboolean
andchar
are encoded using instructions that zero-extend the literal to a value of typeint
at compile-time or run-time. [..]. Thus, most operations on values of actual typesboolean
,byte
,char
, andshort
are correctly performed by instructions operating on values of computational typeint
.
The reason behind this is also specified in that section:
Given the Java Virtual Machine's one-byte opcode size, encoding types into opcodes places pressure on the design of its instruction set. If each typed instruction supported all of the Java Virtual Machine's run-time data types, there would be more instructions than could be represented in a
byte
. [...] Separate instructions can be used to convert between unsupported and supported data types as necessary.
For the details on what all instruction sets are available for various types, you can go through the table in that section.
There is also a table specifying the mapping of actual type to the JVM computational type:
回答2:
The compiler is doing the right thing. Because (a + b) can go beyond the maximum value that can be kept in a byte variable. If you tell the compiler a, b values don't change by using the 'final' keyword it wont complain anymore.
final byte a = 1;
final byte b = 1;
byte c = a + b;
回答3:
JLS 5.6.2: Binary Numeric Promotion covers it:
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type
double
, the other is converted todouble
.Otherwise, if either operand is of type
float
, the other is converted tofloat
.Otherwise, if either operand is of type
long
, the other is converted tolong
.Otherwise, both operands are converted to type
int
.
回答4:
Yes,It's language spec.
The addition(+) operator. while the adding, 'a'
is converts(implicitly casts) to int
type,
b as well to type int
. Hence result
is implicitly of type int
.
Same for -
operator too.
回答5:
While doing the arithmetic operations on any operands the result is stored in this form MAX(int,operand1 type,operand2 type,...operandN type)
Ex:
byte a=10;
byte b=20;
byte c=a+b;
then result of a+b will be stored in the form of MAX(int,operand1 type,operand2 type,...operandN type) in this case MAX(int,byte,byte) the max value is int which is maximum so c will have the int value but c has been declared as byte, and we can't store int(bigger) value into byte(smaller). the same applies for every arithmetic operator.
that is why the error says error: incompatible types: possible lossy conversion from int to byte
回答6:
Compiler is right, declare variables to final or cast to byte:
byte b = 1;
byte c = 22;
byte a = (byte) (b + c);
JAVA : byte+byte = int
:)
来源:https://stackoverflow.com/questions/18483470/is-addition-of-byte-converts-to-int-because-of-java-language-rules-or-because-of