Tip

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

 

Dig Deeper on Core Java APIs and programming techniques

App Architecture
Software Quality
Cloud Computing
Security
SearchAWS
Close