Java 7 and the intricacies of safe and unsafe casting

Open source Java

Java 7 and the intricacies of safe and unsafe casting

By Cameron McKenzie and Sal Pece

TheServerSide.com

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

 

26 Jan 2012

Related Content

Related Resources

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.