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


class Foo{
    public static void main(String args[]){
        final int x=101;

        int y;
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}

компилятор Java понимает, что условие оператора if всегда истинно, и поэтому y всегда будет инициализирован. Нет ошибки компиляции, как и ожидалось.

class Bar{
    public static void main(String args[]){
        final int x;
        x=101;

        int y;      
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}

но когда я разбиваю объявление и инициализацию x на две строки, компилятор, похоже, не получает, что условие всегда истинно и y всегда будет инициализировано.

final int x;
x=101;
byte b;
b=x;
System.out.println(b);

то же самое происходит здесь и компилятор выдает потери точности ошибка.

final int x=101;
byte b;
b=x;
System.out.println(b);

опять же, компилятор может понять, что x находится внутри диапазона b.

2 53

2 ответа:

это связано с тем, как компилятор определяет, будет ли выполняться оператор или нет. Он определяется в JLS #16:

каждая локальная переменная и каждое пустое конечное поле должны иметь определенно назначенное значение, когда происходит какой-либо доступ к его значению.

в вашем случае, компилятор не может определить, что y был определенно назначен и дает вам ошибку. Это потому, что он должен был бы определить, что условие является всегда верно и это возможно только в том случае, если условие в if это константное выражение.

JLS #15.28 определяет постоянные выражения:

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

  • [...]
  • простые имена (§6.5.6.1), что обозначения постоянных величин (§4.12.4).

The JLS #4.12.4 определяет переменные константы как:

переменная примитивного типа или типа String, которая является окончательной и инициализируется выражением константы времени компиляции, называется постоянной переменной.

в вашем случае, final int x = 101; является постоянной переменной, но final int x; x = 101; нет.