Java 7 and the intricacies of safe and unsafe casting
One of the problems with casting is that it does have the potential to cause a loss of precision, especially if the number that gets cast does indeed fall outside of the range of the target type. Here we will explain why this happens.
One of the problems with casting is that it does have the potential to cause a loss of precision, especially if the number that gets cast does indeed fall outside of the range of the target type. Take a look at the following code:
byte me = 10;
short stuff = 1031;
me = (byte)stuff;
System.out.println(me); //prints out 7
In this code snippet, the developer casts a short holding the number 1031 into a byte, despite the fact that 1031 is well outside of the range of a byte. The code compiles, and it even runs, but when it runs, the value that actually gets printed out to the console is 7. Bizarre eh? That’s why we refer to these types of conversions as unsafe casts, and because they are unsafe is why the compiler won’t do them automatically for you.
Casting down: The loss of precision potential
Casting down to a smaller data type is an unsafe cast because it has the potential for losing precision. However, most Java developers are rarely satisfied without being told why, so despite the fact that the following discussion falls way outside of the scope of the exam, I’m going to explain it quickly.
A primitive of type short maps to 16 bits of memory, so at a binary level, the number 1031 looks like this:
0000_0100_0000_0111
However, a byte is only eight bits in size, so when you cast a short into a byte, the JVM just takes the last 8 bits of the 16 bit and moves them into eight bits of memory that the byte will use.
0000_0100_0000_0111 = 1031 (2^0 + 2^1 + 2^2 + 2^11) = (1024 + 4 + 2 + 1)
0000_0100_0000_0111 = 7 (2^0 + 2^1 + 2^2 +2) = ( 4 + 2 + 1)
Casting and binary data truncation
So, after the cast, the byte holds the binary value of 0000_011, which when converted into decimal is the number 7. So when the following code runs, the value that gets spit out to the console is the number 7:
byte me = 10;
short stuff = 1031; // 0000_0100_0000_0111 in binary
me = (byte)stuff; // truncate the short down to 8 bits
System.out.println(me); //prints out 7