2014-09-07 14 views
5

badawczego ten kod:zmienna może już zostały przypisane, gdy nie można przypisać

public class TestFinalAndCatch { 
    private final int i; 

    TestFinalAndCatch(String[] args) { 
     try { 
      i = method1(); 
     } catch (IOException ex) { 
      i = 0; // error: variable i might already have been assigned 
     } 
    } 

    static int method1() throws IOException { 
     return 1; 
    } 
} 

kompilator mówi, że java: variable i might already have been assigned

Ale dla mnie to wygląda sytuacji niemożliwej.

+0

To jest naprawdę dobra odpowiedź na to samo pytanie: http://stackoverflow.com/a/17075219/1354590 – kuporific

+0

A obejście zostało już przedstawione tutaj http://stackoverflow.com/a/13604193/1354590 – kuporific

Odpowiedz

7

i jest ostateczna, więc można ją przypisać tylko raz. Kompilator prawdopodobnie nie jest wystarczająco inteligentny, aby zdać sobie sprawę, że jeśli zostanie zgłoszony wyjątek, pierwsze zadanie nie zostanie wykonane, a jeśli wyjątek nie zostanie zgłoszony, drugie zadanie nie zostanie wykonane.

+0

Tak , ale moja sytuacja, jak gdyby jeszcze inaczej – gstackoverflow

+0

nie .. jej nie jest, jeśli jeszcze. może się zdarzyć, że twoja osoba zostanie przydzielona, ​​a następnie twój kod zgłasza wyjątek – Adi

+0

@Adi w mojej sytuacji jest niemożliwe – gstackoverflow

4

Problem polega na tym, że w tym przypadku kompilator działa na podstawie składni, a nie semantycznej. Istnieją 2 obejścia: Pierwsza baza na ruchomych uchwyt wyjątku od metody:

package com.java.se.stackoverflow; 

public class TestFinalAndCatch { 
    private final int i; 

    TestFinalAndCatch(String[] args) { 
     i = method1(); 
    } 

    static int method1() { 
     try { 
      return 1; 
     } catch (Exception ex) { 
      return 0; 
     } 
    } 
} 

drugiej bazy na wykorzystaniu temporar zmiennej:

package com.java.se.stackoverflow; 

import java.io.IOException; 

public class TestFinalAndCatch { 
    private final int i; 

    TestFinalAndCatch(String[] args) { 
     int tempI; 
     try { 
      tempI = method1(); 
     } catch (IOException ex) { 
      tempI = 0; 
     } 
     i = tempI; 
    } 

    static int method1() throws IOException { 
     return 1; 
    } 
} 
0

Aby rozwiązać ten problem, należy użyć zmiennej lokalnej w catch try bloku, a następnie przypisz ten wynik do zmiennej instancji.

public class TestFinalAndCatch { 
    private final int i; 

    TestFinalAndCatch(String[] args) { 
     int tmp; 
     try { 
      tmp = method1(); 
     } catch (IOException ex) { 
      tmp = 0; 
     } 
     i = tmp; 
    } 

    static int method1() throws IOException { 
     return 1; 
    } 
} 
+0

mmm .. dziękuję, ale nie chcę przezwyciężyć tego problemu)) pytanie o to, jak to jest możliwe – gstackoverflow

0

https://bugs.openjdk.java.net/browse/JDK-6326693?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

Wygląda JDK błędu. A teraz status - Naprawiono. Ale nie mogę znaleźć z której wersji.

+1

Nie, to był błąd, gdy ostatnia zmienna została przypisana w wielu blokach * catch *, a nie w 'try' i 'catch'. Ten błąd został naprawiony w języku Java 8. – kuporific

+0

https://community.oracle.com/thread/2135358?tstart=0 – gstackoverflow

Powiązane problemy