2016-01-19 11 views
0

У меня такой код.Ядро Java Что не так с этим простым синтаксисом

public void test() 
{ 
    final boolean passDay = true; 
    final int status; 
    //if the right side takes place means i need status value below and is set 
    //if only the left side is takes place i dont care about status because i will not use it 
    if(!passDay && ((status=loadStatusValue()))== Constants.YORK_CORK_EMPTY_SET) 
     System.out.println("inside 1");//I DONT CARE ABOUT STATUS VALUE 
    else 
    { 
     if(passDay)System.out.println("BAMBA");//I DONT CARE ABOUT STATUS VALUE 
     else 
     { 
      //HERE STATUS ALWAYS WILL HOLD A VALUE SIMPLYBECAUSE RIGHT SIDE 
      //IS ALREADY EVALUATED BECAUSE passDay=false and !passDay=true 
      System.out.println(status);    
      //I MEAN I USE STATUS ONLY AFTER BEING INITIALIZED 
      //WHY variable status might not have been initialized IS SHOW IF I AM HERE IS BECAUSE STATUS HAS A VALUE. 
     } 
    }     
} 
private boolean compute(){return true;} 
private int loadStatusValue(){return Constants.BOTH_YORK_CORK_SET;}  

Что я думаю, что в этом методе все работы я использовать переменную состояния ИНТ, когда уже был установлен даже не определен в инициализации.

Как вы можете видеть, passDay - это логическое средство, которое может содержать только истину или ложь. Я попробовал hardcoded с ошибкой true и false, а не с компиляцией, показывает, когда отображается ошибка компиляции, вместо этого, когда я делаю что-то вроде hardcode.

final boolean passDay = compute(); 

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

+3

Нет, в отличие от переменных класса перед их использованием необходимо инициализировать локальные переменные. В противном случае вы столкнетесь с ошибкой компилятора. – SomeJavaGuy

+0

, но я использую статус только после инициализации в этом примере. Я использую только статус в System.out.println (status); и на этом этапе статус всегда имеет значение. – chiperortiz

+1

@chiperortiz не обязательно - '&&' оценка коротких цепей, если LHS ложна. –

ответ

4

Пожалуйста, ознакомьтесь с порядком оценки короткого замыкания на Java - (условие1 & & состояние2).

Условие, предшествующее оператору & &, если его значение равно false; выполнение не оценивает другое условие, так как оно не требуется. Независимо от выхода условия2 - false & & Условие2 должно оцениваться как ложное. Попробуйте переупорядочить порядок условий или сначала инициализировать переменную.

надеюсь, что это поможет.

+0

Это не проблема здесь, хотя, если первое условие коротко замыкает оценку, ссылка 'passDay' не используется. Проблема более вероятна, что компилятор не может понять это из-за сложной структуры кода. – Keppil

+0

Но что не так, правая сторона не оценивается? статус не установлен, я знаю, но если правая часть условия не оценена, значит, я не буду использовать переменную статуса ниже, и я больше не буду заботиться о статусе. – chiperortiz

3

&& является оператором короткого замыкания. Это означает, что в следующем выражении:

!passDay && ((status=loadStatusValue()))== Constants.YORK_CORK_EMPTY_SET 

Правый операнд (((status=loadStatusValue()))== Constants.YORK_CORK_EMPTY_SET) вычисляется только, если это !passDaytrue. Это означает, что назначение status произойдет, только если passDay является ложным.

Если вы используете final boolean passDay = compute();, во время компиляции не сможете узнать, вернет ли он или нет compute().

Я подозреваю (без попробовав), что ваш код будет компилироваться с compute(), если вы используете не-короткое замыкание и оператор &, который будет оценивать правый операнд, даже если левый операнд является ложным ,


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

if (passDay) { 
    System.out.println("BAMBA"); 
} else { 
    status = loadStatusValue(); 
    if (status == Constants.YORK_CORK_EMPTY_SET) { 
    System.out.println("inside 1"); 
    } else { 
    System.out.println(status); 
    } 
} 
+0

yep работает, используя &. Я понимаю, что в цикле, но что я пытаюсь сделать, если переменная статуса используется ниже, я имею в виду System.out.println (status), если этот шаг выполняется, переменная состояния всегда будет содержать значение, потому что установлено ((status = loadStatusValue()) Если не задано, я не использую его, потому что не требуется. – chiperortiz

+0

Я подозреваю, что вы переоцениваете глубину статического анализа, сделанного для определения того, определен ли переменная определенно в любой данной ветви. –

+0

Мой код используется, потому что сложнее, и это простой пример об этом ... – chiperortiz

1

В коде, вы установите passDay в final означает, что это значение не может никогда быть изменено по всей программе выполнение. Помните об этом, когда вы делаете условные проверки, например, if(!passDay ...) и т. Д.

Если вы ожидаете, или намереваетесь иметь значение passDay изменилось, то вы можете инициализируетесь в true в начале исполнения, но не delcare, как final

Надеется, что это очищает некоторые вещи.

+0

Это не объясняет, почему 'final boolean passDay = true' работает, но' final boolean passDay = compute() 'does not. –