Friday, December 28, 2007

Exceptions

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

  1. 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();
        }
      }
      
  2. 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:

Anonymous said...

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


Radley Co Tad said...

Very much useful article. Kindly keep blogging

Java Training in Chennai

Java Online Training India

klinik aborsi said...

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