Читать книгу OCP Oracle Certified Professional Java SE 17 Developer Study Guide - Jeanne Boyarsky - Страница 149

Real World Scenaria Overflow and Underflow

Оглавление

The expressions in the previous example now compile, although there's a cost. The second value, 1,921,222, is too large to be stored as a short, so numeric overflow occurs, and it becomes 20,678. Overflow is when a number is so large that it will no longer fit within the data type, so the system “wraps around” to the lowest negative value and counts up from there, similar to how modulus arithmetic works. There's also an analogous underflow, when the number is too low to fit in the data type, such as storing -200 in a byte field.

This is beyond the scope of the exam but something to be careful of in your own code. For example, the following statement outputs a negative number:

System.out.print(2147483647+1); // -2147483648

Since 2147483647 is the maximum int value, adding any strictly positive value to it will cause it to wrap to the smallest negative number.

Let's return to a similar example from the “Numeric Promotion” section earlier in the chapter.

short mouse = 10; short hamster = 3; short capybara = mouse * hamster; // DOES NOT COMPILE

Based on everything you have learned up until now about numeric promotion and casting, do you understand why the last line of this statement will not compile? As you may remember, short values are automatically promoted to int when applying any arithmetic operator, with the resulting value being of type int. Trying to assign a short variable with an int value results in a compiler error, as Java thinks you are trying to implicitly convert from a larger data type to a smaller one.

We can fix this expression by casting, as there are times that you may want to override the compiler's default behavior. In this example, we know the result of 10 * 3 is 30, which can easily fit into a short variable, so we can apply casting to convert the result back to a short:

short mouse = 10; short hamster = 3; short capybara = (short)(mouse * hamster);

By casting a larger value into a smaller data type, you instruct the compiler to ignore its default behavior. In other words, you are telling the compiler that you have taken additional steps to prevent overflow or underflow. It is also possible that in your particular application and scenario, overflow or underflow would result in acceptable values.

Last but not least, casting can appear anywhere in an expression, not just on the assignment. For example, let's take a look at a modified form of the previous example:

short mouse = 10; short hamster = 3; short capybara = (short)mouse * hamster; // DOES NOT COMPILE

So, what's happening on the last line? Well, remember when we said casting was a unary operation? That means the cast in the last line is applied to mouse, and mouse alone. After the cast is complete, both operands are promoted to int since they are used with the binary multiplication operator (*), making the result an int and causing a compiler error.

What if we changed the last line to the following?

short capybara = 1 + (short)(mouse * hamster); // DOES NOT COMPILE

In the example, casting is performed successfully, but the resulting value is automatically promoted to int because it is used with the binary arithmetic operator (+).

OCP Oracle Certified Professional Java SE 17 Developer Study Guide

Подняться наверх