Narrowing type conversion in java

This question already has an answer here:

  • Explicit conversion from int to byte in Java

    4 answers

I am learning Java and completely new to programming. I am trying to understand what is happening behind the scenes in this code:

short c = 234;
byte d = (byte) c;
System.out.println(d);

The output is -22. Can someone explain me what magic happening behind the scenes?

Can someone explain me what magic happening behind the scenes?

no magic at all… check what are the limits that primitives can hold in java

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).
The byte data type can be useful for saving memory in large arrays,
where the memory savings actually matters. They can also be used in
place of int where their limits help to clarify your code; the fact
that a variable’s range is limited can serve as a form of
documentation.

so

short c = 234;

will not fit a byte, that is why you need to cast, the negative resulting value is what you get after that cast operation

A narrowing conversion tries to fit a value with a larger represented type in a narrower represented type.
If the value with a larger represented type doesn’t overflow the narrower represented type, no problem, the value doesn’t change.

For example with byte where the max value is 127, this code will value the byte variable with 127 as it stays in the bounds of the narrow type :

short c = 127;
byte d = (byte) c;
System.out.println(d);

Otherwise you have an overflow. It is your actual case.

For example try this code that overflows by 1 the byte type :

short c = 128;
byte d = (byte) c;
System.out.println(d);

The byte variable will be valued with the next value after 127.
But it doesn’t exist. So the JVM loops on the byte range (-128 to 127).
It uses so the minimal value for a byte : -128.

With short c = 129;, it would produce -127, etc…

The number 234 in binary is ‭11101010‬.

Although this number fits in 8 bits, a byte in java is signed, so the largest possible byte value in java is 127. And when the most significant (leftmost) bit is set, this means “negative number”, so the number you get is negative.

Now, you might wonder why the number you get is -22 when 1101010 is not 22. The answer to this can be found by studying the two’s complement representation of numbers.

Here is the wikipedia article for it: https://en.wikipedia.org/wiki/Two’s_complement

To extend the answer from @Mike Nakis. The value for bytes is -128 – 127. By explicitly telling the compiler to cast with (byte) you say to the compiler to not care about the range constraints and fit it no matter what.

If you did not use the cast the compiler will warn you by printing

incompatible types: possible lossy conversion from short to byte