Is 1/0 a legal Java expression?

前端 未结 8 1209
萌比男神i
萌比男神i 2020-11-27 16:47

The following compiles fine in my Eclipse:

final int j = 1/0;
// compiles fine!!!
// throws ArithmeticException: / by zero at run-time

Java

相关标签:
8条回答
  • 2020-11-27 17:23

    Why bother catching this at compile-time, when you're going to need a run-time variant anyway?

    For example, if you were loading and parsing "0" from a text file, then tried to divide by it, Java would have no idea what you were doing at compile-time because it doesn't know the contents of that external file.

    Also if you were to set any variable to 0 and divide by the variable, Java would have to keep track of every possible value of every variable at every point in the script in order to catch a divide by 0 at compile time.

    Might as well keep things consistent and make it a runtime-only exception.

    0 讨论(0)
  • 2020-11-27 17:31

    Java explicitly requires integer division by zero to trigger an ArithmeticException. The assignment to j can't be elided because that would violate the spec.

    0 讨论(0)
  • 2020-11-27 17:38

    I did some digging into the Bug Database, and discovered some interesting information.

    Bug ID 4178182: JLS doesnt specify behavior for 1/0 as a constant expression

    The following code is illegal:

    class X { static final int i = 1 / 0; }
    

    The value of this compile-time constant is undefined, therefore this has to be a compile-time error. Guy Steele confirmed about 18 months ago that this was indeed the intended behaviour.

    A compile-time constant has to have its value available statically (that's what makes it a compile-time constant ;-) For example, the value of other constants whose values are determined by a constant that contains a division by zero are undefined. This affects the semantics of switch statements, definite assigment and unassignment, etc.

    Bug ID 4089107: javac treats integer division by (constant) zero as an error

    public class zero {
       public static void main(String[] args) {
          System.out.println(1/0);
       }
    }
    

    Running the above yields:

    zero.java:3: Arithmetic exception.
         System.out.println(1/0);
                             ^
    1 error
    

    Bug ID 4154563: javac accepts division by zero constant expressions in case expressions.

    Java compiler crashes while trying to compile next test. This test also crashes all 1.2beta4 compiler versions, but bug is absent in 12.beta3. An example and compiler diagnostics follow:

    public class B {
       public static void main(String argv[]) {
          switch(0){
             case 0/0:
          }
      }
    }
    

    Evaluation: The compiler used to report all attempts to divide by the constant zero as compile-time errors. This was fixed in beta3 so that code would be generated for division by constant zero. Unfortunately this bug was introduced. The compiler should handle a division by zero in a case expression gracefully.

    Conclusion

    So the question of whether or not 1/0 should compile was a contested topic of discussion, with some people quoting Guy Steele claiming that this should be a compile time error, and others saying that it shouldn't. It seems that ultimately it's decided that it's neither a compile-time error nor a compile-time constant.

    0 讨论(0)
  • 2020-11-27 17:41

    Well, if you look into the Double class, you will see the following:

    /**
     * A constant holding the positive infinity of type
     * <code>double</code>. It is equal to the value returned by
     * <code>Double.longBitsToDouble(0x7ff0000000000000L)</code>.
     */
    public static final double POSITIVE_INFINITY = 1.0 / 0.0;
    

    The same calculation is made in the Float class, except with floats instead of doubles. Basically, 1/0 returns a really, really big number, larger than Double.MAX_VALUE.

    This following code:

    public static void main(String[] args) {
        System.out.println(Double.POSITIVE_INFINITY);
        System.out.println(Double.POSITIVE_INFINITY > Double.MAX_VALUE);
    }
    

    Outputs:

    Infinity
    true
    

    Note the special case in printing out Double.POSITIVE_INFINITY. It prints out a string, though it's regarded as a double.

    To answer the question, yes it is legal in Java, but 1/0 resolves to "infinity" and is treated differently from standard Doubles (or floats, or so on and so forth).

    I should note that I do not have the slightest clue how or why it was implemented this way. When I see the above output, it all seems like black magic to me.

    0 讨论(0)
  • 2020-11-27 17:41

    It is legal in compiling point of view, but it would throw an exception if executed!

    the reason... well programming must allow flexibility therefore all the expressions and every single code you type is a variable for the compiler, thus in the mathematical expression X/Y the compiler does not care if the Y variable value is (Y==0) or any other number for the compiler this is a variable... if the compiler would have to look at values also, that would be considered runtime, wouldn't it.

    0 讨论(0)
  • 2020-11-27 17:42

    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.)

    0 讨论(0)
提交回复
热议问题