The following compiles fine in my Eclipse:
final int j = 1/0; // compiles fine!!! // throws ArithmeticException: / by zero at run-time
Java prevents many "dumb code" from even compiling in the first place (e.g. "Five" instanceof Number
doesn't compile!), so the fact this didn't even generate as much as a warning was very surprising to me. The intrigue deepens when you consider the fact that constant expressions are allowed to be optimized at compile time:
public class Div0 { public static void main(String[] args) { final int i = 2+3; final int j = 1/0; final int k = 9/2; } }
Compiled in Eclipse, the above snippet generates the following bytecode (javap -c Div0
)
Compiled from "Div0.java" public class Div0 extends java.lang.Object{ public Div0(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_5 1: istore_1 // "i = 5;" 2: iconst_1 3: iconst_0 4: idiv 5: istore_2 // "j = 1/0;" 6: iconst_4 7: istore_3 // "k = 4;" 8: return }
As you can see, the i
and k
assignments are optimized as compile-time constants, but the division by 0
(which must've been detectable at compile-time) is simply compiled as is.
javac 1.6.0_17
behaves even more strangely, compiling silently but excising the assignments to i
and k
completely out of the bytecode (probably because it determined that they're not used anywhere) but leaving the 1/0
intact (since removing it would cause an entirely different program semantics).
So the questions are:
1/0
actually a legal Java expression that should compile anytime anywhere? Because Integers in Java does not have Infinity values. So Dividing a number by zero is not permitted for Integers in Java.
To sum things up, in this article we saw how division by zero works in Java. Values like INFINITY and NaN are available for floating-point numbers but not for integers. As a result, dividing an integer by zero will result in an exception. However, for a float or double, Java allows the operation.
Expressions perform the work of a Java program. Among other things, expressions are used to compute and assign values to variables and to help control the execution flow of a program. The job of an expression is two-fold: perform the computation indicated by the elements of the expression and return some value.
Is
1/0
actually a legal Java expression that should compile anytime anywhere?
Yes.
What does JLS say about it?
Nothing specific ... apart from saying that division by zero will result in a runtime exception. However, the JLS acknowledges that possibility of runtime exceptions in the following definition:
"A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following: ..."
(Emphasis added.) So the following would NOT compile:
switch(i) { case 1: case 1 + 1: case 1 / 0: // compilation error. }
If this is legal, is there a good reason for it?
Good question. I suppose that it is a way to throw ArithmeticException
though that is hardly a plausible reason. A more likely reason for specifying Java this way is to avoid unnecessary complexity in the JLS and compilers to deal with an edge case that is rarely going to bite people.
But this is all by the by. The fact is that 1/0
is valid Java code, and no Java compiler should ever flag this as a compilation error. (It would be reasonable for a Java compiler to issue a warning, provided that there was a compiler switch to turn it off.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With