28 Ağustos 2020 Cuma

Try With Resources

Giriş
try-with-resources kullanımıyla finally yazmaya gerek kalmıyor. Aslında finally bazen kafa karıştırıcı olabilir.

Örnek
Elimizde şöyle bir kod olsun. finally her zaman çalıştığı için sonuç olarak "Intelligent Boy!" alırız.
public static void main(String[] args) {
  System.out.println(checkBoy());
}
public static String checkBoy() {
  try {
    return "Good Boy!";
  } catch(Exception e) {
    return "Bad Boy!";
  } finally {
    return "Intelligent Boy!";
  }
}
Örnek
Kapatılmasını istediğimiz her kaynak bir değişkene atanmak zorundadır. Şöyle yaparız
try (Connection connection = DriverManager.getConnection(...);
     Statement statement = connection.createStatement();
     ResultSet resultSet = statement.executeQuery(sql)) {
    // ...   
}
Bazen kapatılan kaynak kendisine constructor içinde verilen kaynağı da kapatır. Bu durumda şöyle yapabiliriz
try (BufferedWriter bw = new BufferedWriter(new FileWriter(...)) {
    // ...   
}
try İçinde Exception Fırlatılırsa
Sadece finally işletilir
Örnek
Elimizde şöyle bir kod olsun
public static class Resource implements AutoCloseable {

  public Resource() throws Exception {
    throw new Exception("Exception from constructor");
  }

  public void doSomething() throws Exception {
    throw new Exception("Exception from method");
  }

  @Override
  public void close() throws Exception {
    throw new Exception("Exception from closeable");
  }
}

public static void main(String[] args) {
  try(Resource r = new Resource()) {
    r.doSomething();
  } catch (Exception ex) {
    ex.printStackTrace();
  }
}
Yakalanan exception nesnesinin detailMessage alanında "Exception from constructor" görürüz. finally block çalıştırılmaz.

work İçinde Exception Fırlatılırsa
Throwable nesnesinin suppressed alanında görebiliriz.

Örnek
Şöyle yaparız
try (Connection c = DriverManager.getConnection(url)) {
    work();
} catch (Exception e) {
    throw new Error("Insert failed", e);
}
Eğer hem work() hem de Connection.close() metodu içinde exception fırlatılırsa close() tarafından fırlatılan exception Throwable nesnesinin suppressed alanında görürüz.
Açıklaması şöyle
This will close your connection or generally the passed AutoCloseable appropriately. And will handle the shadowing of the exception by using the Throwable.addSuppressed() method.
Çıktı olarak şuna benzer bir şey alırız. Koyu kısım suppressed olan ve close() metodundan gelen exception.
>>> work()
  >>> close()
  MyException: Exception in work()
    at AutoClose.work(AutoClose.java:11)
    at AutoClose.main(AutoClose.java:16)    Suppressed: java.lang.RuntimeException: Exception in close()
      at AutoClose.close(AutoClose.java:6)
      at AutoClose.main(AutoClose.java:17)

Hiç yorum yok:

Yorum Gönder