Подтвердить что ты не робот

Почему переменная Java, деленная на ноль, не создает ошибку времени компиляции?

Возможный дубликат:
Является ли 1/0 законным выражением Java?

Почему этот код компилируется?

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

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

Если я посмотрю в файле скомпилированного класса, я вижу, что B был оценен до 30, а A все равно 7/0.

Насколько я понимаю, JSL выражение, в котором вы делите на ноль, не является константой.

Ссылка: JLS 15.28

Мой оператор выше из-за этой строки:

Постоянное выражение времени компиляции представляет собой выражение, обозначающее значение примитивного типа

Следовательно, деление на ноль не оценивается до примитивного значения.

То, что я действительно не понимаю, почему компилятор разрешает это? Чтобы быть понятным, мой код выше сбой во время выполнения с помощью "java.lang.ExceptionInInitializerError"

Как мне кажется, компилятор угрожает любой конечной статической переменной в качестве константы и оценивает ее время компиляции. Это означает, что компилятор уже попытался оценить A, но поскольку он был делением на ноль, он просто позволил ему пройти. Ошибка компиляции. Но это кажется очень очень странным... Компилятор знает, что это деление на ноль, и что это приведет к сбою во время выполнения, но, тем не менее, это не означает ошибку компиляции!

Может кто-нибудь объяснить мне, почему?

4b9b3361

Ответ 1

Выбрасывать java.lang.ExceptionInInitializerError является единственным правильным поведением.

Если ваш код не был скомпилирован, вполне допустимая программа Java была бы отклонена, и это было бы ошибкой.

Единственной правильной альтернативой помещению 7/0 в скомпилированный код было бы фактически явно выбросить ExceptionInInitializerError, но насколько полезнее это?

Компилятор знает, что это деление на ноль и что он приведет к сбою во время выполнения, но, тем не менее, флаг ошибки компиляции!

Собственно, я бы не согласился с этим... может ли эта программа сбой?

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();

        }
    }
}

Ответ 2

JLS 15.28 Constant Expression:

Выражение константы времени компиляции представляет собой выражение, обозначающее значение примитивного типа или String , которое не завершается внезапно и составлено с использованием только следующего:

...

Следовательно, 7/0 не является константой времени компиляции, так как ее оценка резко завершается из-за деления на ноль. Таким образом, он рассматривается как регулярное выражение во время выполнения и генерирует исключение во время выполнения.