„Sneaky Throws“ v jazyku Java

1. Prehľad

V Jave sneaky throw koncept nám umožňuje hodiť ľubovoľnú kontrolovanú výnimku bez toho, aby sme ju výslovne definovali v podpise metódy. Toto umožňuje vynechanie hodí deklarácia účinne napodobňujúca charakteristiky runtime výnimky.

V tomto článku sa pozrieme na niektoré príklady kódu, ako sa to v praxi deje.

2. O Záludných hodoch

Skontrolované výnimky sú súčasťou Java, nie JVM. V bytecode môžeme hádzať ľubovoľnú výnimku odkiaľkoľvek, bez obmedzení.

Java 8 priniesla nové pravidlo odvodenia typu, ktoré uvádza, že a hodí T sa odvodzuje ako RuntimeException kedykoľvek je to dovolené. To dáva možnosť realizovať záludné hody bez pomocnej metódy.

Problém s záludné hody je to, že pravdepodobne budete chcieť nakoniec chytiť výnimky, ale kompilátor Java vám neumožňuje chytiť tajne vyhodené kontrolované výnimky pomocou obsluhy výnimiek pre ich konkrétny typ výnimky.

3. Zaludne hody v akcii

Ako sme už spomenuli, kompilátor a Jave Runtime môžu vidieť rôzne veci:

public static void sneakyThrow (Throwable e) hodí E {throw (E) e; } private static void throwsSneakyIOException () {sneakyThrow (new IOException ("sneaky")); }

Kompilátor vidí podpis s hodí T odvodené od a RuntimeException typu, takže umožňuje šírenie nekontrolovanej výnimky. Java Runtime nevidí žiadny typ v hodoch, pretože všetky hody sú rovnaké jednoduché hod e.

Tento rýchly test demonštruje scenár:

@Test public void whenCallSneakyMethod_thenThrowSneakyException () {try {SneakyThrows.throwsSneakyIOException (); } catch (Výnimka ex) {assertEquals ("záludný", ex.getMessage (). toString ()); }}

Je možné hádzať kontrolovanú výnimku pomocou manipulácie s bytovým kódom, príp Thread.stop (hoditeľný), ale je to chaotický a neodporúča sa to.

4. Používanie anotácií Lombok

The @SneakyThrows anotácia od Lomboku vám umožňuje hádzať kontrolované výnimky bez použitia hodí vyhlásenie. To sa hodí, keď potrebujete vyvolať výnimku z metódy vo veľmi obmedzujúcich rozhraniach, ako je Spustiteľné.

Povedzme, že hodíme výnimku zvnútra a Spustiteľné; postúpi sa iba Vlákno 's nespracovaná obsluha výnimky.

Tento kód vyhodí Výnimka napríklad, takže nie je potrebné, aby ste to balili do a RuntimeException:

verejná trieda SneakyRunnable implementuje Runnable {@SneakyThrows (InterruptedException.class) public void run () {throw new InterruptedException (); }}

Nevýhodou tohto kódu je, že nemôžete zachytiť kontrolovanú výnimku, ktorá nie je deklarovaná; takže sa nebude kompilovať.

Tu je správny formulár na uplatnenie zákernej výnimky:

@SneakyThrows public void run () {try {throw new InterruptedException (); } catch (InterruptedException e) {e.printStackTrace (); }}

A toto je test tohto správania:

@Test public void whenCallSneakyRunnableMethod_thenThrowException () {try {new SneakyRunnable (). Run (); } catch (Výnimka e) {assertEquals (InterruptedException.class, e.getStackTrace ()); }}

5. Záver

Ako sme videli v tomto článku, kompilátor Java môže byť podvedený, aby s označenými výnimkami zaobchádzal ako s nezačiarknutým.

Ako vždy je kód k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found