2012-06-08 17 views
8

Biorąc pod uwagę, że w zasadzie chcą wyeliminować sprawdzane wykorzystanie wyjątku i przekształcić je z czasem przebiegu wyjątki, ja zwykle robi coś takiego:Zamień zaznaczony wyjątek na wyjątek środowiska wykonawczego?

try { 
    file.read(); 
} catch (IOException e){ 
    throw new RuntimeException(e); 
} 

Istnieje kilka wad w ten sposób, ale ten, który mi się irytuje większość jest taka, że ​​mój wyjątek środowiska wykonawczego zawiera zagnieżdżony stacktrace. Zasadniczo chciałbym ponownie rzucić "IOException" jako RuntimeException (lub "IORuntimeException") z oryginalnym komunikatem i stacktrace, więc mogę uniknąć bezużytecznego zagnieżdżonego stacktrace. "Fakt", w którym ponownie rzuciłem wyjątek gdzieś pośrodku, wydaje mi się po prostu bezużytecznym hałasem.

Czy to możliwe? Czy jest jakaś biblioteka, która to robi?

+0

Czy [this] (http://robaustin.wikidot.com/rethrow-exceptions) jest pomocny? –

+2

Jeśli jesteś zirytowany zagnieżdżonymi śladami stosu, będziesz nienawidzić większości frameworków i bibliotek, które mają tendencję do intensywnego korzystania z nich. Po prostu przyzwyczaiłbym się do tego, gdybym był tobą. – artbristol

+0

@KazekageGaara, dobrze. Załatwię to, jeśli napiszesz to jako odpowiedź. – missingfaktor

Odpowiedz

4

Project Lombok pozwala całkowicie wyłączyć zaznaczone wyjątki.

+2

Wystarczająco sprawiedliwe, ale to dla mnie za dużo. Wolałbym po prostu zrobić to gdzieś w swoim miejscu. – krosenvold

+3

Wątpię, czy istnieje niehakowate rozwiązanie problemu, który próbujesz rozwiązać. – missingfaktor

3
class IORuntimeException extends RuntimeException { 

    final IOException ioex; 

    public IORuntimeException(IOException ioex) { 
     this.ioex = ioex; 
    } 

    @Override 
    public String getMessage() { 
     return ioex.getMessage(); 
    } 

    @Override 
    public StackTraceElement[] getStackTrace() { 
     return ioex.getStackTrace(); 
    } 

    //@Override 
    // ... 
} 

(Pełny tekst dostępny here klasy, jak produkowane przez Eclipse "Generuj Delegowanie Formy" makro).

Zastosowanie:

try { 
    ... 
} catch (IOException ioex) { 
    throw new IORuntimeException(ioex); 
} 
+0

Problem z tym podejściem polega na tym, że nie można go uogólnić na dowolny typ "wyjątku", a tym samym powoduje zbyt wiele powielania i duplikowania kodu. – missingfaktor

+0

Cóż, zawsze możesz zrobić [to] (http://ideone.com/9OOwd). – aioobe

+0

Tak, ale informacja o typie zostanie utracona. Tylko wtedy, gdy Java będzie reifikowała generyczne ... wtedy moglibyśmy to zrobić z lekami generycznymi. – missingfaktor

3

Kontynuacja z moim komentarzem. Oto article, który musi rzucić nieco światła na problem. Używa sun.misc.Unsafe do ponownego zgłaszania wyjątków bez ich zawijania.

2

Jeśli rozważasz używać innych odpowiedzieć za niebezpiecznych (nie polecam, ale w każdym razie), innym rozwiązaniem jest nadużywanie leków generycznych rzucać sprawdzonej wyjątek z tego złego parę metod (od http://james-iry.blogspot.co.uk/2010/08/on-removing-java-checked-exceptions-by.html):

@SuppressWarnings("unchecked") 
    private static <T extends Throwable, A> 
    A pervertException(Throwable x) throws T { 
     throw (T) x; 
    } 


    public static <A> A chuck(Throwable t) { 
     return Unchecked. 
     <RuntimeException, A>pervertException(t); 
    } 

Możesz również sprawdzić com.google.common.base.Throwables.getRootCause(Throwable) i wydrukować ślad stosu (głównego).

0

brzmi rzeczywiście trzeba sprawdzane wyjątki

0

Jako Java 8 jest inny sposób:

try { 
    // some code that can throw both checked and runtime exception 
} catch (Exception e) { 
    throw rethrow(e); 
} 

@SuppressWarnings("unchecked") 
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T { 
    throw (T) throwable; // rely on vacuous cast 
} 

* Więcej informacji here.

Powiązane problemy