Why can not I add two bytes and get an int and I can add two final bytes get a byte?
From the JLS 5.2 Assignment Conversion
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.
In short the value of the expression (which is known at compile time, because it is a constant expression) is representable in the type of the variable that is byte.
Consider your expression
final byte x = 1;
final byte y = 2;
byte z = x + y;//This is constant expression and value is known at compile time
So as summation fits into byte it does not raise an compilation error.
Now if you do
final byte x = 100;
final byte y = 100;
byte z = x + y;// Compilation error it no longer fits in byte
Is addition of byte converts to int because of java language rules or because of jvm?
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:
Why explicit cast required when adding int with byte?
27
is a literal. The compiler knows that it is representable in a byte
(from -128 to 127).
a + b
is an expression involving variables. Its result may not be representable in a byte
How to add two bytes together in Java, with wrap around if there is overflow
Because you're only working with byte
, you can store the result of your addition in a larger primitive type, such as an int
. By doing this, you'll have easy access to the overflow bit, which you can extract (using bitwise operations) and add to the existing sum:
int sum = b1 + b2;
sum += (sum >> 8) & 1;
String s3 = String.format("%8s", Integer.toBinaryString(sum & 0xFF)).replace(' ', '0');
System.out.println("sum of byte 1 and byte 2: " + s3); // should be 11111111
If the value of the overflow bit is 0
, then nothing happens. But if it's 1
, overflow occurred and the bit will wrap around.
Why there is no error when a final int is assigned to a byte
When you initialize a final
variable with a constant expression, it will become a compile-time constant. Essentially, when the code is compiled, it will just hardcode the value everywhere your variable is added. You can see this in the byte code:
0 bipush 123
2 istore_1 [i]
3 bipush 123
5 istore_2 [b]
As you can see, it pushes the value 123
directly into the byte
(same as byte b = 123
), and that is a valid value for a byte
. It would not work with a value that is outside the allowed range for bytes.
If the variable is not final
(or not initialized with a constant expression), then the compiler will see it as a normal variable, and normal rules for assigning are applied. Meaning that to assign an int to a byte it needs to be casted:
int i = 123;
byte b = (byte) i;
Which produces this bytecode:
0 bipush 123
2 istore_1 [i]
3 iload_1 [i]
4 i2b
5 istore_2 [b]
Is there a more efficient way to combine 2 bytes and get the resulting decimal value?
To concatenate two bytes together efficiently, some bitwise arithmetic is required. However, to achieve the result that you want, we need to operate on the bytes as int
values, as the result may be represented by more than 8 bits.
Consequently, we need to ensure that we're always working with the least significant 8 bits of each value (keep in mind that negative integers are represented using leading 1s in binary instead of 0s).
This can be accounted for by performing a bitwise-and of each value with 0xFF
:
byte higher = (byte) 0b01110110;
byte lower = (byte) 0b10010010;
int concatenated = ((higher & 0xFF) << 8) | (lower & 0xFF);
System.out.println(concatenated);
As expected, the output of this snippet is:
30354
Why this code is throwing error?
Java does not have an addition operator for bytes, so to compute b1+b2
the values are converted to int
and the sum is calculated as with ints. You get the error because there is no implicit conversion from int to byte because of possible loss of precision.
You have to use an implicit casting conversion to get the sum as byte
:
b3=(byte)(b1+b2);
By the way, this is not an "exception" but a compile-time error. Exceptions are produced when you run a program.
Related Topics
Capture and Log the Response Body
How to Initialize List<String> Object in Java
Javafx - Border Radius <-> Background Color
How to Change a Bitmap's Opacity
Failed to Import New Gradle Project: Failed to Find Build Tools Revision *.0.0
How to Start Activity in Adapter
What Exactly Is a Context in Java
How to Get the Selected Value of a Spinner
How to Get Count of Number Methods Used in a Jar File
Why Can Not I Add Two Bytes and Get an Int and I Can Add Two Final Bytes Get a Byte
Easiest Way to Convert a List to a Set in Java
How to Use Jsp/Jstl to Generate Dynamic CSS/JavaScript Files
Failed to Resolve: Com.Google.Firebase:Firebase-Core:16.0.1
Best Way to Implement View.Onclicklistener in Android
Create Pdu for Android That Works with Smsmessage.Createfrompdu() (Gsm 3Gpp)