2015-06-29 20 views
11

Mam bardzo głupie pytanie dla ciebie :)try-catch i zmienne końcowe

Na przykład, mam następujący fragment kodu:

class MyClass { 

    public static void main (String[] args) { 

     final String status; 

     try { 
      method1(); 
      method2(); 
      method3(); 
      status = "OK"; 
     } catch (Exception e) { 
      status = "BAD"; // <-- why compiler complains about this line?? 
     } 

    } 

    public static void method1() throws Exception { 
     // ... 
    } 

    public static void method2() throws Exception { 
     // ... 
    } 

    public static void method3() throws Exception { 
     // ... 
    } 

} 

Pytanie jest wewnątrz: dlaczego kompilator narzeka na tej linii ?

IntelliJ IDEA mówi, że Variable 'status' might already have been assigned to.

Ale, jak widzę, nigdy nie docieramy do linii (gdzie ustawiamy status = "OK") w przypadku wyjątkowej sytuacji. Więc zmienna status będzie BAD i wszystko powinno być w porządku. A jeśli nie mamy żadnego wyjątku, otrzymamy OK. I ustawimy tę zmienną tylko RAZ raz.

Jakieś przemyślenia na ten temat?

Dzięki za pomoc!

+1

kompilator nie jest tak mądry, a jeśli deklarują, że metoda może rzucać kompilator wyjątek przyzwyczajenie być stara się go sprawdzić, więc dla uproszczenia nie dopuszcza takie rzeczy się wydarzy – Toumash

Odpowiedz

10

Kompilator Java nie widzi, co ty i ja widzimy - że albo status zostanie ustawione na "OK" lub zostanie ustawione na "BAD". Zakłada się, że status można ustawić i wyjątek jest zgłaszany, w którym to przypadku zostanie przypisany dwukrotnie, a kompilator generuje błąd.

Aby to obejść, przypisz tymczasową zmienną do bloku try - catch i przypisz raz zmienną final.

final String status; 
String temp; 

try { 
    method1(); 
    method2(); 
    method3(); 
    temp = "OK"; 
} catch (Exception e) { 
    temp = "BAD"; 
} 

status = temp; 
+0

Myślę, że nadal jest to ważny błąd, co jeśli ten wątek zostanie przerwany i wyrzuci 'InterruptedException' zaraz po przypisaniu –

+1

@JigarJoshi Nie może rzucić' InterruptedException' (może coś inaczej, ale nie to i prawdopodobnie nie w tym kodzie). –

+0

jeśli był w osobnym wątku i został wywołany na 'interrupt()' –

2

Co się stanie, jeśli kod, który spowodował wyjątek, wystąpił pod numerem postatus = "OK"? Przyczyna pojawienia się błędu wydaje się dość oczywista.

Weź to na przykład:

final String status; 

try { 
    status = "OK": 
    causeException(); 
}catch(Exception e) { 
    status = "BAD"; 
} 

void causeException() throws Exception() { 
    throw new Exception(); 
} 

Spowodowałoby realokacja zmienną, dlatego pojawi się błąd.

+2

Zmienna jest ostateczna . Ponowne przydzielanie jest zabronione. – swinkler

+4

@swinkler To jest punkt, przez który przechodzę. Błąd występuje, ponieważ powyższy kod jest możliwy. Człowieku, co się dzieje z StackOverflow teraz-a-dni .. –

Powiązane problemy