2011-11-12 13 views
6

Jaki jest najlepszy sposób na uzyskanie praktyka Exception Przejrzystość w Javie przy użyciu anonimową klasę wewnętrzną, aby uruchomić jakiś kod.rzucanie Sprawdzone Wyjątki od zajęć Anonymous wewnętrzne

Częstym wzór, który widziałem w czasie rzeczywistym za pomocą kodu jest jakiś interfejs pseudo typu Runnable określić pewien kontekst dla jakiegoś określonego kodu. Najlepszym przykładem, jaki mogę wymyślić w JDK, jest java.security.PrivilegedExceptionAction.

try { 
    boolean success = AccessController.doPrivileged(
     new PrivilegedExceptionAction<Boolean>() { 
      @Override 
      public Boolean run() throws Exception { 
       // do something 
       // read file 
       FileInputStream fileInputStream = 
        new FileInputStream(new File("someFile")); 
       return true; 
      } 
     } 
    ); 
} catch (PrivilegedActionException e) { 
    if (e.getCause() instanceof FileNotFoundException) { 
     // handle IO exception 
    } else { 
     // impossible no other checked exception 
    } 
} 

Nawet odczytaniu kodu można wyraźnie zobaczyć kod wewnętrzny rzuca tylko plik nie został znaleziony, ale utracone korzyści sprawdzonych wyjątków rozmówca nie zdaje sobie sprawy z tego, co jest faktycznie rzucony wyjątek. Powszechnym błędem byłoby wprowadzenie kodu do anonimowej klasy wewnętrznej, która spowodowałaby nowy wyjątek, a kod nie zmuszałby cię do obsługi tego wyjątku.

Co chcę jest coś, co jest poniżej, jest to rodzaj zachowania osiągalne bez zmiany języka?

public interface PrivilegedExceptionAction<T,V... extends Throwable> 
{ 
    public T run() throws V; 
} 
+0

Uważam, że anonimowe klasy wewnętrzne są generalnie złym pomysłem, głównie dlatego, że nie można ich ponownie wykorzystać ani rozszerzyć. Ale to kolejny powód. Jestem też zainteresowany każdą odpowiedzią. – user949300

+0

Spójrz na http://blogs.sun.com/briangoetz/entry/exception_transparency_in_java – alexsmail

+0

Widziałem propozycję Briana pod lambda projektu, niestety nie jest dostępny w Java 6 – bluphoenix

Odpowiedz

3

Nie rozumiem, dlaczego nie. Poniższy kod zadziałał.

interface RunIt < E extends Exception > 
{ 
    void run () throws E ; 
} 

class App 
{ 
    public static void main (String [ ] args) 
    { 
     RunIt <RuntimeException> r = new RunIt <RuntimeException> () 
     { 
      public void run () 
      { 
       throw new RuntimeException () ; 
      } 
     } ; 
     r . run () ; 
    } 
} 
+0

Co byś zrobił, gdybyś musiał rzucić więcej niż jeden wyjątek? Czy masz RunIt2 . Sądzę, że nie jest tak źle. Musiałbym wybrać, który interfejs będzie używany w zależności od sprawdzonych wyjątków, które spodziewam się wyrzucić. – bluphoenix

+0

Jeśli chcesz rzucić więcej niż jeden wyjątek, istnieją 2 opcje. (1) jak mówisz E1 przedłuża wyjątek, E2 rozszerza wyjątek. (2) Możesz wybrać E, aby być super klasą wszystkich wyjątków, które można rzucać. Jeśli wybierzesz 1, interfejs może wyglądać jak RunIt , aby umożliwić wiele rodzajów sprawdzanych wyjątków. (Jeśli potrzebujesz więcej niż potrzebujesz, możesz ustawić nadmiar na RuntimeException.) Jeśli wybierzesz 2 tego rodzaju, pokonasz cel ćwiczenia. To nie jest świetne rozwiązanie, ale działa. – emory