Exceptions
Closures are allowed to throw exceptions. We use the throws
keyword to declare which exceptions are
thrown by a closure:
{ long => void throws InterruptedException } wait = { long millis => Thread.sleep(millis); }; try { wait.invoke(2000); System.out.println("hi"); } catch (InterruptedException e) { e.printStackTrace(); }
A closure may throw more than one exception:
try { FileOutputStream fos = new FileOutputStream("primes"); try { { int, long => void throws IOException, InterruptedException } writeAndWait = { int value, long millis => fos.write(value); Thread.sleep(millis); }; writeAndWait.invoke(17, 2000); System.out.println("first"); writeAndWait.invoke(19, 2000); System.out.println("second"); } finally { fos.close(); } } catch (IOException | InterruptedException e) { e.printStackTrace(); }
When we assign a closure to a variable of function type, the closure must not throw more than is declared in the function type.
// constructor FileWriter throws IOException which is a subclass of // Exception { String => void throws Exception } truncate = { String name => new FileWriter(name).close(); }; { => double throws Exception } next = { => Math.random() }; // Math.random() does not throw any exception
Exception Transparency
If we pass a closure that throws exceptions to some method, we might want these exceptions are propagated from the method.
If we used ordinary type parameter for exception, we could have passed in only a block that throws one exception.
But what if we want to accept a block that throws any number of exceptions and we want exceptions are transparently
propagated to the caller? We have to use exception type parameters.
The exception type parameter is declared using the throws
keyword and stands for any number of exceptions.
// method performTwice throws the same exceptions as the block passed in static <throws E> void performTwice({ => void throws E } block) throws E { block.invoke(); block.invoke(); } static void passBlockThrowingNoExceptions() { performTwice({ => System.out.println("no exception..."); }); } static void passBlockThrowingOneException() { try { // the block passed to performTwice throws one exception // (InterruptedException) // the compiler checks that we catch this exception performTwice({ => System.out.println("waiting..."); Thread.sleep(2000); }); } catch (InterruptedException e) { e.printStackTrace(); } } static void passBlockThrowingMoreExceptions() { try { // the block passed to performTwice throws two exceptions // (InterruptedException and IOException) // the compiler checks that we catch these exceptions performTwice({ => Thread.sleep(2000); new FileWriter("x").close(); }); } catch (InterruptedException | IOException e) { e.printStackTrace(); } }
If we do not want to propagate exceptions, we can invoke a closure in the try block:
static <throws E> void logAndPerform( String desc, { => void throws E } block) { System.out.printf("start: %s...%n", desc); try { block.invoke(); } catch (Exception e) { e.printStackTrace(); } System.out.printf("end: %s%n", desc); } public static void main(String[] args) { logAndPerform("doing nothing", { => System.out.println("hi"); }); logAndPerform("sleeping", { => Thread.sleep(2000); }); logAndPerform("sleeping and truncating", { => Thread.sleep(2000); new FileWriter("x").close(); }); }
Exercises
- Fill in the type of p.
static void m() throws FileNotFoundException, InterruptedException { //... } public static void main(String[] args) { p = { => m(); }; try { p.invoke(); } catch (FileNotFoundException | InterruptedException e) { e.printStackTrace(); } }
- Declare method forEach that performs an operation on each item of a collection. The operation is described by a closure and may throw an exception (one or more).
Solutions
{ => void throws FileNotFoundException, InterruptedException } p = { => m(); };
static <T, throws E> void forEach( Iterable<T> items, { T => void throws E } block) throws E { for (Iterator<T> it = items.iterator(); it.hasNext(); ) { block.invoke(it.next()); } } public static void main(String[] args) { List<String> nums = Arrays.asList("first", "second", "third"); forEach(nums, { String s => System.out.println(s); }); }
3 comments:
Klik Aja Di Bawah Ini
Pemesanan: 087733776655
http://obatkuat-57.com/
Jual Obat Pembesar Penis Vigrx Plus
Alat Bantu Sex Pria Dan Wanita
Rajanya Obat Kuat Sex
Obat Perangsang Wanita, Obat Gairah Wanita
Obat Pembesar Payudara Monyok, Payudara Kencang
Alat Pembesar Payudara Montok
Alat Pembesar Penis
Alat Sex Pria Boneka Moderen
Obat Pengental Sperma
Minyak Pembesar Penis, Obat Pemanjang Penis
Obat Hernia Paling Ampuh
Obat Pelangsing Badan, Melangsingkan Tubuh
Obat Perapet Vagina
Obat Peninggi Badan, Meninggikan Bada
Obat Pembesar Pantat, Pembesar Bokong
Obat Pemerah Bibir, Pemerah Puting
Obat Pemutih Wajah Alami Tensung Cream
Obat Penggemuk Badan
Obat Penghilang Tatto Permanen Herbal Alami
Kondom Antik Pria
Rajanya Obat Kuat Pria
Alat Bantu Sex Wanita Antik
Alat Bantu Sex Pria
Obat Kuat Herbal
Vimax Obat Pembesar Alat Vital
Cara Memutihkan Selangkangan dan Ketiak
Obat Pelangsing Badan Fatloss Jimpness Beauty
Selaput Dara Perawan Buatan
Very much useful article. Kindly keep blogging
Java Training in Chennai
Java Online Training India
Jual Obat Aborsi Asli | Obat Cytotec Asli | 082241083319
jual obat aborsi pills cytotec asli manjur untuk menggugurkan kandungan usia 1 - 6 bulan gugur tuntas.CYTOTEC OBAT ASLI sangat efektif mengatasi TELAT DATANG BULANdan menjadikan anda gagal hamil , CYTOTEC adalah OBAT ABORSI 3 JAM BERHASIL GUGUR TUNTAS dengan kwalitas terbaik produk asli pfizer nomor 1 di dunia medis
JUAL OBAT ABORSI DI BANGKALAN
JUAL OBAT ABORSI DI BANYUWANGI
JUAL OBAT ABORSI DI BLITAR
JUAL OBAT ABORSI DI KANIGORO
JUAL OBAT ABORSI DI BOJONEGORO
JUAL OBAT ABORSI DI BONDOWOSO
JUAL OBAT ABORSI DI GRESIK
Post a Comment