Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java byte type is weird?

Tags:

java

Could someone explain the java byte type?

This doesn't compile:

byte b1 = 9;
byte b2 = 1;
byte b3 = b1 + b2;

While this does:

byte b4 = 9 + 1;
byte b5 = (char)(9+1);

In addition, assignment to a long doesn't work, even if the value fits into a byte:

byte b7 = (long)127;

It gets even weirder with wrappers

This compiles:

Byte b6 = (int)3;

But this doesn't:

Integer i = (byte)3;
like image 479
Andrew Liu Avatar asked Feb 20 '12 18:02

Andrew Liu


People also ask

Why is Java byte 128?

In Java the byte data type is made up of 8 bits; it represents signed integer using 2s complement. So the most significant bit (MSB) holds the charge thus remaining are 7 bits. Each place could hold 2 values 0 or 1. Least value it could hold is (2 power 7) = -128.

Is there a byte type in Java?

The eight primitive data types supported by the Java programming language are: byte: The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive).

Should I use byte or int in Java?

byte datatype has a range from -128 to 127 and it requires very little memory (only 1 byte). It can be used in place of int where we are sure that the range will be very small. The compiler automatically promotes the byte variables to type int, if they are used in an expression and the value exceeds their range.

Can I convert int to byte in Java?

The byteValue() method of Integer class of java. lang package converts the given Integer into a byte after a narrowing primitive conversion and returns it (value of integer object as a byte).


2 Answers

Java Language Specification 5.6.2 Binary Numeric Promotion: "Otherwise, both operands are converted type int".

So Java converts both operands to and int, so the result of the addition is an int.

Addition: The difference between b3 and b4 is, that in b4 it's an Constant Expression (15.28), in b3 it's literal.

like image 118
0x434D53 Avatar answered Sep 28 '22 08:09

0x434D53


b6 does work due to compile-time narrowing of literal constants. b7 does not work because compile-time narrowing is limited to all primitives but long (kind of strange, no idea why)

The interesting part is §5.2 of the 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.
A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is :

 - Byte and the value of the constant expression is representable in the
   type byte.

 - Short and the value of the constant expression is representable in
   the type short.     

 - Character and the value of the constant expression is representable in the type char.

If the type of the expression cannot be converted to the type of the variable by a conversion permitted in an assignment context, then a compile-time error occurs.

No idea why i does not work though - widening should work just fine and in fact, the compiler should generate something like Integer.valueOf((byte)3); anyhow. Using the explicit call works as expected, i.e. widening is happening.

Interestingly enough using the eclipse Java compiler Integer i = (byte) 3; compiles just fine, which leads me to believe you just found a bug in javac - congratulations! (well either that or a bug in the eclipse compiler; but eclipse's behavior seems the correct one to me). FWIW I've reported the bug against javac to oracle..

Finding the right part in the JLS was less work than formatting this that it's somewhat readable - so probably easier if you follow the link instead.

like image 30
Voo Avatar answered Sep 28 '22 09:09

Voo