12

Possible Duplicate:
Is 1/0 a legal Java expression?

Why does this code compile?

class Compiles {
    public final static int A = 7/0;
    public final static int B = 10*3;

    public static void main(String[] args) {}
}

If I take a look in the compiled class file, I can see that B has been evaluated to 30, and that A still is 7/0.

As far as I understand the JSL an expression where you divide by zero is not a constant.

Ref: JLS 15.28

My above statement is due to this line:

A compile-time constant expression is an expression denoting a value of primitive type

Hence dividing by zero is not evaluated to a primitive value.

What I really dont understand is why the compiler allows this anyway? Just to be clear, my code above crashes runtime with a "java.lang.ExceptionInInitializerError"

As it seems to me the compiler threats any final static variable as a constant and evaluates it compile time. That means that the compiler already has tried to evaluate A, but since it was a division by zero it just let it go through. No compile time error. But this seems very very bizarre... The compiler knows it is a divide by zero and that it will crash runtime but nevertheless it doesn't flag a compile error!

Can anyone explain to me why?

1
  • 1
    Is there any instance of division by zero producing compile-time errors at all? If you divided by zero in normal procedural code you would get an ArithmeticException in runtime, so I see nothing surprising about this getting through the compiler too. Commented Feb 12, 2011 at 20:20

2 Answers 2

7

To throw an java.lang.ExceptionInInitializerError is the only correct behavior.

If your code did not compile, a perfectly valid Java program would have been rejected, and that would have been a bug.

The only correct alternative to putting 7/0 in the compiled code, would actually be to explicitly throw a ExceptionInInitializerError, but how much more useful is that?

The compiler knows it is a divide by zero and that it will crash runtime but nevertheless it does flag a compile error!

Actually, I wouldn't agree with that... would this program crash?

class Compiles {
    public final static int A = 7/0;
    public final static int B = 10*3;

    public static void main(String[] args) {}

}

public class Test {

    // Application entry point.
    public static void main(String[] args) {
        try {
            new Compiles();

            launchTheMissiles();

        } catch (ExceptionInInitializerError e) {

            doUsefulStuff();

        }
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Your program will not crash. But mine will. So you will always put initialization of new objects in a try/catch??
Yes. I always put try/catch around instantiations of ExceptionInitializerError-classes. ;-D
By that logic there should be no compile time errors at all, for you could enclose any statement with a try-catch. Is that a fair assessment?
@Allohvk, unclear to me how that would work. What exception would something like aoeu]aoeu(ueao throw? The Eclipse compiler can compile it to throw an Error but it is still not a valid Java program. It would be very hard and complicated to formalize error recovery. When does the actual error end, and where does the catch clause start? For example, should this be an acceptable Java program: try{ao]/*%+^/eu}catch}}catch(Error e){}
Ok, yeah, you're right. So, you could rephrase your previous comment as "By that logic, there should be no compile time errors for syntactically valid programs." (which is obviously not desirable.) So I agree, there is a middle ground here, and nothing would have prevented the creators of disallowing 7/0.
|
2

JLS 15.28 Constant Expression:

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:

...

Therefore 7/0 is not a compile-time constant, since its evaluation completes abruptly due to division by zero. So, it's treated as a regular run-time expression, and throws an exception in runtime.

3 Comments

That was what I said! I totally agree. But I find it weird that it doesnt flag it as a compile error, since the compiler already has evaluated the expression?
If you agree that it is not a compile-time constant, then you shouldn't be surprised that the evaluation is deferred to runtime, and consequently throw an exception.
that's probably a patch to justify existing javac behavior (can't change it due to backward compatibility). the spec could have very well said: "blah blah, and it is a compile time error if the expression doesn't compute"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.