Java Programlama

advertisement
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
case
case
case
case
} }
Jonathan: System.out.println("Jonathan is red."); break;
GoldenDel: System.out.println("Golden Delicious is yellow."); break;
RedDel: System.out.println("Red Delicious is red."); break;
Winesap: System.out.println("Winesap is red."); break;
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
Download