Java Programlama İstisnalar, Numaralandırmalar, Otomatik Kutulama ve Açıklama Notları
İstisnalar (Exceptions) Programlar beklenmedik durumlar ortaya çıkarabilir Bu beklenmedik durumlar, önceden, hata kodlarına dayalı olarak yönetilmekteydi (örn: C ve Linux) Yeni programlama dillerinde hata yönetim mekanizmaları (exception handling machanism) kullanılmaktadır Hata yönetim mekanizmaları daha güçlü ve esnek bir şekilde beklenmedik durumların yönetimini sağlarlar
İstisna Hiyerarşisi Java da istisnalar Throwable sınıfından türetilir ve aşağıdaki hiyerarşiye sahiptir.
İstisna Ortaya Çıkarma ve Yakalama İstisnalar, hatalı durumların yakalanmasını ve kontrol edilmesini sağlarlar java.lang.exception sınıfından türetilirler Hatayla karşılaşan kod istisna fırlatır (throw an exception) Hatanın kontrol edilmesini sağlayan kod istisnayı yakalar (catch the exception)
Yakalanmamış İstisna Örneği - main metotu class Exc0 { public static void main(string args[]) { int d = 0; int a = 42 / d; System.out.println("Deneme"); Java çalışma ortamı, sıfıra bölme girişimine rastladığı zaman, yeni bir istisna nesnesi oluşturur ve bu istisnayı fırlatır
İstisna Yaşam Döngüsü Bir istisna fırlatıldığında, bu istisna bir istisna yöneticisi tarafından yakalanarak yönetilmelidir İstisna yakalanana kadar metot çağırım yığınında (method call stack) yukarı doğru ilerler Bir önceki slayttaki örnekte kendi istisna yöneticimizi yazmadık İstisna Java çalışma ortamı tarafından sağlanan varsayılan istisna yöneticisi tarafından yakalanmış Hatanın başladığı yerden itibaren yığını izini ekrana yazdırılmış ve Program akışı yarıda kesilmiştir
İstisna Yakalama Kendi istisna yöneticimizi yazarak aşağıdaki şekilde istisnayı yakalayabiliriz: try { // İstisna üretebilecek birşeyler yap catch (Exception e) { // Hata mesajini String değişkenine ata String errormsg = e.getmessage(); //...
Yakalanmış İstisna Örneği public static void main(string args[]) { int d, a; try { // monitor a block of code. d = 0; a = 42 / d; System.out.println("This will not be printed."); catch (ArithmeticException e) { // catch divide-by-zero error System.out.println("Division by zero."); System.out.println("After catch statement.");
Sınıf Metotlarındaki İstisnalar Metotlar bir istisna ortaya çıkarabileceklerini throws ifadesi ile belirtirler Bu metotları çağıran metotlar, ya bu istisnayı yakalamalıdır ya da throws ifadesini kullanmalıdır Örnek: void method() throws Exception { //... try { method(); catch (Exception e) { //...
Yakalanmamış İstisna Örneği - Sınıf Metotu class Exc1 { static void subroutine() { int d = 0; int a = 10 / d; public static void main(string args[]) { Exc1.subroutine();
Yığın İzi (Stack Trace) İstisna yakalanana kadar metot çağırım yığınında (method call stack) yukarı doğru ilerler Sorunu anlamak için, istisnanın yığın izini printstacktrace() metodunu kullanarak ekrana yazabilirsiniz Bir sonraki slayttaki kodu çalıştırarak, ekrana yazılan yığın izine dikkat edin
Yığın İzi Örneği public static void main(string args[]) { int d, a; try { // monitor a block of code. d = 0; a = 42 / d; System.out.println("This will not be printed."); catch (ArithmeticException e) { // catch divide-by-zero error e.printstacktrace(); System.out.println("After catch statement.");
Throw ile İstisna Fırlatma throw anahtar kelimesi ile kendimiz istisna fırlatabilirsiniz Büyük bir yazılım projesinde kendi istisnalarımızı oluşturup, gerektiğinde bu istisnaları ortaya çıkarmalı ve yakalamalıyız İstisna ortaya çıkaran kod örneği: boolean error; if (error) throw new Exception("Error condition");
Uygulama Önceki örnekteki yakalanmamış istisna kodundaki istisnayı, fırlatıp ve yakalayarak (throws ve catch ekleyerek) ekrana bir hata mesajı yazdırınız.
Farklı İstisna Tiplerinin Yakalanması Exception alt sınıfları tanımlanabilir throws ifadesi birden fazla istisna tipini belirtebilir Birden fazla catch ifadesi kullanılarak farklı istisna tiplerinin farklı şekillerde kontrol edilmesi sağlanabilir İstisna sadece ilk uyumlu catch ifadesi tarafından kontrol edilir Örnek: try { //... catch (ExceptionSubClass e) { //... catch (Exception e) { //...
Finally Bloğu İstisna oluşması durumunda dahi çalışması istenilen kod parçacıkları finally bloğu içerisine yazılır Örnek: try { //... catch (Exception e) { //... finally { // try-catch bloğundan sonra çalıştırılır
Denetlenmeyen İstisnalar (Unchecked Exceptions) (1/2) Normal istisnalar denetlenen istisnalardır (checked exceptions) Metotlar try-catch bloğuna sahip olmalı yada throws idadesini kullanmalıdır Derlenme zamanında bu kural kontrol edilir Denetlenen istisnalar gereksiz kod yazımına neden olabilir Bir istisna hiç bir zaman gerçekleşmeyecek olsa bile, kontrol edilmelidir (yakalanmalıdır) Denetlenmeyen istisnaların kontrol edilmesi zorunlu değildir Ancak eğer gerekli ise kontrol edilebilir java.lang.runtimeexception ve bu sınıfın alt sınıfları denetlenmeyen istisnalardır
Denetlenmeyen İstisnalar (Unchecked Exceptions) (2/2) RuntimeException sınıfının java.lang paketinde bulunan ve sık karşılaşılan alt sınıfları: ClassCastException eğer temel sınıftan alt sınıfa dinamik çevrim gerşekleştirilemezse IllegalArgumentException eğer bir metota, kabul edilemeyecek bir parametre gönderilirse IndexOutOfBoundsException eğer varolmayan bir dizi elemanına erişilmeye çalışılmışsa NullPointerException eğer nesne referansı hafızada yer almayan bir nesneyi gösteriyorsa ve nesnenin üyesine erişilmeye çalışılırsa (nesne değişkeni: null)
Kendi İstisnalarınızın Oluşturulması Java nın kendi istisnaları pek çok yaygın hatayı yönetebilmenizi sağlar Ancaki kendi uygulamalarınıza özgü durumları veya hataları yönetmek için kendi istisnalarınızı oluşturmak isteyebilirsiniz Kendi istisnanızı oluşturmak için Exception sınıfından bir alt sınıf oluşturmalısınız Kendi istisnanız için en azından bir yapıcı tanımlamanız ve tostring() metodunun üzerine yazmanız uygun olacaktır
Yeni İstisna Sınıfı: MyException class MyException extends Exception { private int detail; MyException(int a) { detail = a; public String tostring() { return "MyException[" + detail + "]";
Yeni İstisna Sınıfının Kullanımı (1/2) static void compute(int a) throws MyException { System.out.println("Called compute(" + a + ")"); if (a > 10) throw new MyException(a); System.out.println("Normal exit");
Yeni İstisna Sınıfının Kullanımı (2/2) public static void main(string args[]) { try { compute(1); compute(20); catch (MyException e) { System.out.println("Caught " + e);
Zincirleme İstisnalar (Chained Exceptions) JDK 4 ile birlikte gelmiş bir özelliktir Bir istisna ile başka bir istisnayı ilişkilendirmeyi sağlar İkinci istisna birinci istisnanın nedenini tanımlar Zincirleme istisnaların kullanımı için Throwable sınıfına iki yeni yapıcı ve iki yeni metot eklenmiştir Throwable(Throwable istisnanedeni) Throwable(String mesaj, Throwable istisnanedeni) Throwable getcause() Throwable initcause(throwable istisnanedeni)
Zincirleme İstisna Örneği (1/2) static void demoproc() { // create an exception NullPointerException e = new NullPointerException("top layer"); // add a cause e.initcause(new ArithmeticException("cause")); throw e;
Zincirleme İstisna Örneği (2/2) public static void main(string args[]) { try { demoproc(); catch (NullPointerException e) { // display top level exception System.out.println("Caught: " + e); // display cause exception System.out.println("Original cause: " + e.getcause());
JDK 7 ve İstisnalar JDK 7 ile birlikte istisnalarla ilgili üç yeni özellik gelimiştir Kaynaklarla birlikte try (try-with-resources) Çoklu yakalama Daha net yeniden fırlatma (final rethrow) Kaynalarla birlikte try, bir kaynağın (örneğin dosyanın) onunla işimiz bittikten sonra otomatik olarak kapatılmasını sağlar. Dosyalar konusunda anlatılacaktır Çoklu yakalama, aynı catch bloğu ile birden fazla istisna tipinin yakalanmasını sağlar Daha net yeniden fırlatma
JDK 7 ve İstisnalar JDK 7 ile birlikte istisnalarla ilgili üç yeni özellik gelimiştir Kaynaklarla birlikte try (try-with-resources) Çoklu yakalama Kaynalarla birlikte try, bir kaynağın (örneğin dosyanın) onunla işimiz bittikten sonra otomatik olarak kapatılmasını sağlar. Dosyalar konusunda anlatılacaktır Çoklu yakalama, aynı catch bloğu ile birden fazla istisna tipinin yakalanmasını sağlar Bir sonraki slaytta çoklu yakalama örneği gösterilmektedir
Çoklu İstisna Yakalama Örneği public static void main(string args[]) { int a = 10, b = 0; int vals[] = { 1, 2, 3 ; try { int result = a / b; // generate an ArithmeticException // vals[10] = 19; // generate an ArrayIndexOutOfBoundsException // This catch clause catches both exceptions. catch (ArithmeticException ArrayIndexOutOfBoundsException e) { System.out.println("Exception caught: " + e); System.out.println("After multi-catch.");
Numaralandırmalar (Enumerations) Numaralandırma, adlandırılmış sabitlerden oluşan bir listedir Numaralandırmalar, kavramsal olarak basit olsalar da pek çok diğer dilde bulunan bu özellik, pek çok programda kullanılabilir JDK 5 ten itibaren Java ya eklenmiştir Java da bir numaralandırma bir sınıf tipi tanımlar Bu diğer dillerdeki numaralandırma yapılarına göre esneklik sağlar Örneğin C++ da numaralandırmalar, sadece adlandırılmış tamsayı sabitlerdir
Numaralandırmaların Tanımlanması (1/2) Numaralandırma, enum anahtar sözcüğü kullanılarak oluşturulur Aşağıda değişik elma türlerini listeleyen basit bir numaralndırma tanımlanmıştır: enum Apple { Jonathan, GoldenDel, RedDel, Winesap, Cortland
Numaralandırmaların Tanımlanması (2/2) enum Apple { Jonathan, GoldenDel, RedDel, Winesap, Cortland Jonathan, GoldenDel gibi tanımlayıcılar, numaralandırma sabitleri olarak adlandırılır Her biri Apple sınıfının, public, static ve final birer üyesidir Her birinin tipi ise tanımlandıkları numaralandırmanın tipidir: Apple
Numaralandırma Kullanımı Numaralandırmalar bir sınıf tipi tanımlasa da, new anahtar kelimesi kullanarak bir enum örneği oluşturamazsınız Aksine, bir numaralandırma değişkenini, tıpkı temel veri tiplerini tanımlayıp kullandığınız gibi kullanmalısınız Apple ap; ap = Apple.RedDel; if (ap == Apple.RedDel) //
Numaralandırma Kullanım Örneği (1/2) public static void main(string args[]) { Apple ap; ap = Apple.RedDel; // Output an enum value. System.out.println("Value of ap: " + ap); System.out.println(); ap = Apple.GoldenDel; // Compare two enum values. if (ap == Apple.GoldenDel) System.out.println("ap contains GoldenDel.\n");
Numaralandırma Kullanım Örneği (2/2) switch (ap) { case Jonathan: System.out.println("Jonathan is red."); break; case GoldenDel: System.out.println("Golden Delicious is yellow."); break; case RedDel: System.out.println("Red Delicious is red."); break; case Winesap: System.out.println("Winesap is red."); break; case Cortland: System.out.println("Cortland is red."); break;
values() ve valueof() Metotları Tüm numaralandırmalar otomatik olarak, önceden tanımlı iki metot içerir: values() ve valueof() public static enum-tipi[] values() public static enum-tipi valueof(string param) values() metotu, numaralandırma sabitlerinin listesini içeren bir dizi döndürür valueof() metotu kendisine göderilen karakter katarına karşılık gelen numaralandırma sabitini döndürür
values() ve valueof() Metotları Örneği public static void main(string args[]) { Apple ap; System.out.println("Here are all Apple constants"); // use values() Apple allapples[] = Apple.values(); for (Apple a : allapples) System.out.println(a); System.out.println(); // use valueof() ap = Apple.valueOf("Winesap"); System.out.println("ap contains " + ap);
Numaralandırma Sınıf Tipleri Java numaralandırması bir sınıf tipidir Her ne kadar new kullanarak yeni bir örnek oluşturulamazsa da, bunun dışında diğer sınıflarla aynı yeteneklere sahiptir Örneğin bir numaralandırma tipine aşağıdaki özellikler eklenebilir: Yapılandırıcılar Değişkenler Metotlar Hatta numaralandırma tipipyle bir arayüzü gerçekleştirebilirsiniz
Genişletilmiş Apple Numaralandırması enum Apple { Jonathan(10), GoldenDel(9), RedDel(12), Winesap(15), Cortland(8); private int price; // price of each apple // Constructor Apple(int p) { price = p; int getprice() { return price;
Genişletilmiş Apple Numaralandırması Kullanımı public static void main(string args[]) { Apple ap; // Display price of Winesap. System.out.println("Winesap costs " + Apple.Winesap.getPrice() + " cents.\n"); // Display all apples and prices. System.out.println("All apple prices:"); for (Apple a : Apple.values()) System.out.println(a + " costs " + a.getprice() + " cents.");
Numaralandırmalar Enum Sınıfını Temel Alır Numaralandırmalar java.lang.enum sınıfını temel alır Bu sınıftan devralınan metotlar: final int ordinal() final int compareto(enum-tipi e) Final int equals(enum-tipi e) ordinal(), numaralandırma sabitinin, sabitler listesindeki konumunu döndürür compareto(), iki sabitin ordinal değerlerini karşılaştırır equals(), bir numaralndırma sabitini diğer herhangi bir nesneyle eşitlik bakımından karşılaştırabilirsiniz
java.lang.enum Metotları Örneği (1/2) public static void main(string args[]) { Apple ap, ap2, ap3; // Obtain all ordinal values using ordinal(). System.out.println("Here are all apple constants and their ordinal values: "); for (Apple a : Apple.values()) System.out.println(a + " " + a.ordinal()); ap = Apple.RedDel; ap2 = Apple.GoldenDel; ap3 = Apple.RedDel; System.out.println();
java.lang.enum Metotları Örneği (2/2) if (ap.compareto(ap2) < 0) System.out.println(ap + " comes before " + ap2); if (ap.compareto(ap2) > 0) System.out.println(ap2 + " comes before " + ap); if (ap.compareto(ap3) == 0) System.out.println(ap + " equals " + ap3); System.out.println(); if (ap.equals(ap2)) System.out.println("Error!"); if (ap.equals(ap3)) System.out.println(ap + " equals " + ap3); if (ap == ap3) System.out.println(ap + " == " + ap3);
Tip Uyumlulaştırıcıları (1/2) Java dilindeki temel veri tipleri: int, double gibi Bu tipler için nesnelerin kullanılması performans açısından bir dezavantaja neden olur Bu nedenle temel veri tipleri nesne hiyerarşisi içerisinde yer almazlar Object sınıfından türetilmemişlerdir Temel tipler bir performans avantajı sağlasa da, bu tipler için bir nesne temsiline ihtiyaç duyduğumuz durumlar olabilir Örneğin, Java da gerçekleştirimi olan pek çok veri yapısı nesneler üzerinde çalışır
Tip Uyumlulaştırıcıları (2/2) Bu durumlarla başa çıkabilmek için tip uyumlulaştırıcıları (type wrappers) kullanılır Bunlar temel veri tipini bir nesne içinde sarmalayan sınıflardır Tip uyumlulaştırıcıları: Character Boolean Double, Float, Long, Integer, Short, Byte (sayısal tip uyumlulaştırıcılar)
Character Tip Uyumlulaştırıcısı Yapılandırıcı: Character(char c) Bir Character nesnesinde tutulan char değerini elde etmek için: char charvalue()
Boolean Tip Uyumlulaştırıcısı Yapılandırıcılar: Boolean(bool b) Boolean(String strbool) Bir Boolean nesnesinde tutulan bool değerini elde etmek için: boolean booleanvalue()
Sayısal Tip Uyumlulaştırıcıları (1/2) Tüm sayısal tip uyumlulaştırıcıları, herhangi bir değerden veya değerin karakter katarından yapılandırılabilmesini sağlayan yapıcılar içerir. Örneğin Integer için tanımlanmış yapıcılar: Integer(int b) Integer(String strint) Örneğin Double için tanımlanmış yapıcılar: Double(double d) Double(String strdouble)
Sayısal Tip Uyumlulaştırıcıları (2/2) Sayısal tip uyumlulaştırıcılarının hepsi Number sınıfından türetilmiştir. Number sınıfında, sayının farklı tiplerde değerlerini döndürebilen aşağıdaki metotlar tanımlanmıştır: byte bytevalue() double doublevalue() float floatvalue() int intvalue() long longvalue() short shortvalue()
Sayısal Tip Uyumlulaştırıcısı Örneği class Wrap { public static void main(string args[]) { Integer iob = new Integer(100); int i = iob.intvalue(); System.out.println(i + " " + iob); // displays 100 100
Otomatik Kutulama JDK 5 ten itibaren Java diline iki önemli özellik eklenmiştir: Otomatik kutulama (autoboxing) Otomatik kutudan çıkarma (auto-unboxing) Otomatik kutulama, belirli bir tipte nesne gerektiğinde, bir temel tipin otomatik olarak karşılık gelen tip uyumlulaştırıcısına çevrilmesidir Otomatik kutudan çıkarma ise, tersi işlemin otomatik olarak gerçekleşmesidir Bu özellikler, pek çok algoritmanın kodlanmasını programcı açısından kolaylaştırmıştır Hataların önlemeye yardımcı olur ve jenerikler için de çok önemlidir
Otomatik Kutulama Örneği class AutoBox { public static void main(string args[]) { Integer iob = 100; // autobox an int int i = iob; // auto-unbox System.out.println(i + " " + iob); // displays 100 100
Otomatik Kutulama ve Metotlar // Take an Integer parameter and return an int value; static int m(integer v) { return v; // auto-unbox to int public static void main(string args[]) { // Pass an int to m() and assign the return value // to an Integer. Here, the argument 100 is autoboxed // into an Integer. The return value is also autoboxed // into an Integer. Integer iob = m(100); System.out.println(iOb);
Deyimlerde Otomatik Kutulama ve Kutudan Çıkartma (1/2) class AutoBox3 { public static void main(string args[]) { Integer iob, iob2; int i; iob = 100; System.out.println("Original value of iob: " + iob); // The following automatically unboxes iob, // performs the increment, and then reboxes // the result back into iob. ++iob; System.out.println("After ++iob: " + iob);
Deyimlerde Otomatik Kutulama ve Kutudan Çıkartma (2/2) // Here, iob is unboxed, the expression is // evaluated, and the result is reboxed and // assigned to iob2. iob2 = iob + (iob / 3); System.out.println("iOb2 after expression: " + iob2); // The same expression is evaluated, but the // result is not reboxed. i = iob + (iob / 3); System.out.println("i after expression: " + i);
Açıklama Notları (Annotations) Java kaynak kodları için üst veriler (metadata) Tanımlamalara uygulanır Sınıfların, değişkenlerin, metotların ve yerel değişkenlerin tanımlanmalarında üst veri bildirmek için kullanılır @ karakteri ile başlar Ön tanımlı açıklama tipleri: @Deprecated - @Override - @SuppressWarnings Warning types: deprecation, unused, null Örnek: @SuppressWarnings("unused")
Ön Tanımlı Açıklama Notları (1/2) @Override Sadece metotlar üzerinde kullanılabilen bir işsaretleyici nottur Bir üst sınıftaki metotun üzerine yazıldığını belirtir Eğer üst sınıfta böyle bir metot yoksa bir derleme zamanı hatası oluşur @Deprecated Bir tanımlamanın eski olduğunu ve aynı işlemin artık farklı bir şekilde gerçekleştirildiğini belirten işretleyici nottur Örneğin, Java 4 te bulunan ama Java5 te bulunmayan bir metot, Java5 te @deprecated olarak işaretlenir
Ön Tanımlı Açıklama Notları (2/2) @SuppressWarnings Derleyici tarafından verilebilecek bir ya da daha çok uyarının göz ardı edileceiğini belirtir Bastırılacak uyarılar, karakter katarı formunda adlarıyla belirtilir Örnek: @SuppressWarnings("unused") Bastırılacak uyarı tiplerinden bazılarına karşılık gelen karakter katarları: all tüm uyarılar unused kullanılmayan yerel değişkenler veya özel metotlar için uyarılar deprecation eskiden tanımlı metotların veya değişkenlerin kullanımı için uyarılar null null analizi ile ilişkili uyarılar