简体   繁体   中英

Why, In Java arithmetic, overflow or underflow will never throw an Exception?

During Java Arithmetic operation , JVM do not throw Underflow or Overflow Exception. So many time we come across unexpected results and wondering what went wrong.

While in case of .NET technology we have Overflow and Undeflow exception.

So my question is that , why Java was design not to throw this exception during arithmetic operation

This was likely a combination of factors:

  1. The big languages prior to Java used unchecked arithmetic. Well-known algorithms prone to numerical overflow tended to account for the potential overflow already without relying on checked arithmetic.
  2. Checked arithmetic introduces significant overhead in algorithms making heavy use of arithmetic instructions, which would put Java at a substantial disadvantage especially for benchmarks.
  3. Some algorithms rely on silent numerical overflow/underflow. If arithmetic operations were checked, rewriting these algorithms could quickly become non-trivial.
  4. Checked arithmetic is not necessary to ensure memory safety (as opposed to other JVM checks like null pointers and array bounds).

The .NET virtual execution environment (now part of the ECMA-335 standard) introduced separate instructions for checked and unchecked arithmetic, allowing it to independently address the performance and safety concerns of developers working in modern managed languages.

It probably has to do with performance as Indoknight said. Java provided the tools to care for overflow, so if you need to detect it you could do it. You also have long and BigInteger and can use those to avoid your int overflows.

You should see this answer from a similar question in stackoverflow. How does Java handle integer underflows and overflows and how would you check for it?

When Java was originally created, the language designers did that way. I'm not sure why, but if it had it certainly would have a performance penalty in raising Exceptions.

"The lesson for language designers is that it may be worth reducing the likelihood of silent overflow. This could be done by providing support for arithmetic that does not overflow silently. Programs could throw an exception instead of overflowing, as does Ada, or they could switch to a larger internal representation automatically as required to avoid overflow, as does Lisp. Both of these approaches may have performance penalties associated with them. Another way to reduce the likelihood of silent overflow is to support target typing, but this adds significant complexity to the type system [Modula-3 1.4.8]."

Courtesy - Java puzzlers traps and pitfalls by Joshua Bloch & Neal Gafter

Java was based on C and C++ which is based on Assembly. In none of these languages is an exception thrown, partly because Exceptions were not in those languages when the arithmetic operations were designed.

It is much safer to use a larger type like long or double or BigInteger or BigDecimal in the first place and only use smaller types if you are really sure this is inappropriate.

It doesn't have to be a common problem if you use these wider types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM