2012-11-28 17 views
49

Ponieważ uważam, że jest to dobra praktyka programistyczna, tworzę wszystkie zmienne (lokalne lub instancji) final, jeśli mają być napisane tylko raz.Końcowe przypisanie zmiennej z próbą/przechwytywaniem

, zauważam jednak, że gdy zmienna cesja może rzucić wyjątek nie można dokonać powiedział zmienna końcowa:

final int x; 
try { 
    x = Integer.parseInt("someinput"); 
} 
catch(NumberFormatException e) { 
    x = 42; // Compiler error: The final local variable x may already have been assigned 
} 

Czy istnieje sposób to zrobić bez uciekania się do zmiennej tymczasowej? (lub czy nie jest to odpowiednie miejsce na ostateczny modyfikator?)

+1

Wątpię, możesz to zrobić bez zmiennej tymczasowej. – NPE

+8

'final int x = makeX();' zdecydowanie. (funkcja "próbuj złapać") –

+2

Szokujące, że JDK [nadal nie ma 'tryParse'] (http://stackoverflow.com/questions/1486077/java-good-way-toapsapsulate-integer-parseint) . –

Odpowiedz

44

Jednym ze sposobów na zrobienie tego jest wprowadzenie zmiennej tymczasowej (innej niż final), ale powiedziałeś, że nie chcesz tego robić.

Innym sposobem jest przeniesienie obu gałęzi kodu do funkcji:

final int x = getValue(); 

private int getValue() { 
    try { 
    return Integer.parseInt("someinput"); 
    } 
    catch(NumberFormatException e) { 
    return 42; 
    } 
} 

, czy nie jest to praktyczna zależy od dokładnego przypadku użycia.

Podsumowując, tak długo, jak x jest lokalną zmienną o odpowiedniej skali, najbardziej praktycznym podejściem ogólnym może być pozostawienie go w stanie innym niż final.

Jeśli, z drugiej strony, x jest zmienny element, moja rada byłoby użyć nie- final czasowe podczas inicjalizacji:

public class C { 
    private final int x; 
    public C() { 
    int x_val; 
    try { 
     x_val = Integer.parseInt("someinput"); 
    } 
    catch(NumberFormatException e) { 
     x_val = 42; 
    } 
    this.x = x_val; 
    } 
} 
+0

Dla zakresu lokalnego zgadzam się z Tobą, jednak najczęściej występuje w przypadku zmiennych instancji. – dtech

+0

Przypuszczam, że może to odzwierciedlać błąd, nie może utworzyć statycznego odniesienia do niestatycznej metody getValue(), więc przypuszczalnie używamy funkcji statycznej ,, może to być niewłaściwa prywatna statyczna int getValue() .. @ NPE – gks

+0

Jeśli this.x jest obiektem typu Integer, potrzebujesz trochę więcej (niestety). Jeśli zostawisz x_val niezadeklarowany, kompilator będzie skarżył się, że nie został zainicjowany. Jeśli powrót do bloku catch ma wartość null, musisz wstępnie zainicjować wartość NULL i redundantnie przypisać wartość null do catch dla jasności (to moje preferencje) lub mieć pusty haczyk. –

2

Nie, to nie jest właściwe miejsce, wyobraź sobie, że masz więcej następnie 1 Oświadczenie w swoim bloku try i catch, pierwszy mówi: x = 42. Po niektórych innych Wypowiedziach blok try nie powiedzie się, a następnie przechodzi do bloku catch, gdzie twój say x = 30. Teraz zdefiniowałeś x dwa razy.

+9

Kompilator jest wystarczająco inteligentny, aby wiedzieć, które instrukcje wyszczególniają te wyjątki. Może nie być to możliwe we wszystkich przypadkach, ale tak jak kompilator może ci powiedzieć w niektórych przypadkach o martwym kodzie itp., Powinien on być w stanie dowiedzieć się, czy finał będzie działał. – Stefan

+0

Aby wspierać to, co powiedział @Stefan, Clang jest w stanie to zrozumieć podczas kompilowania Swift. –

Powiązane problemy