BLM202E Data Structures Lecture 11: Generics Bilgisayar Mühendisliği Bölümü Öğr. Gör. Musa AYDIN 2014 – 2015 (Bahar) BLM202E Data Structures - 2015 Spring Jenerikler (Java Generics) • Java programlama dilinin güçlü özelliklerinden biri de Jenerikler (generics) konusudur; • C++ dilindeki “Template” (Şablon) kavramı ile hemen hemen aynı işlevlere sahip • java’da jenerikler ( generics), ön tanımlı (built in) dil özelliği (language feature) olarak gelmektedir ve jenerikleri kullanarak çok daha güvenilir ve sağlam uygulamalar geliştirebilirsiniz. 9.5.2015 BLM202E Data Structures - 2015 Spring 2 Jenerikler (Java Generics) • Yazılım geliştirme süreçlerinde en önemli sorunlardan biri hatalarla (bug) uğraşmak ve bunları olabildiğince engellemeye çalışmaktır. • Ne kadar sağlam ve özenle uygulama geliştirdiğinizi düşünürseniz düşünün, muhakkak uygulamalarınızda bir süre sonra hatalar meydana gelecektir. • Java, Jenerik (Generic) özelliği ile uygulamalarınızda ki hataları minimuma indirmeyi amaçlar. Dahası uygulamalarınızda kullandığınız kodların çok daha etkili bir şekilde tasarlanmasına yardımcı olur. 9.5.2015 BLM202E Data Structures - 2015 Spring 3 Jenerikler (Java Generics) • Öte yandan jenerikler, Java’nın sunduğu Java Collection Framework kütüphanesi tarafından kullanıldığından öğrenilmesi ve uygulamaya konması son derece önemli. 9.5.2015 BLM202E Data Structures - 2015 Spring 4 Jenerikler (Java Generics) • Aşağıda jenerik kullanılmadan oluşturulmuş basit bir sınıf var. Bu sınıf Object tipinde tüm nesneleri sınıf değişkenine atayabiliyor. • Primitive tipler dışında herhangi bir Java nesnesini sınıfın add metoduna geçirebilirsiniz. 9.5.2015 BLM202E Data Structures - 2015 Spring 5 Jenerikler (Java Generics) • Buraya kadar her şey çok güzel. Fakat, bu sınıfa özel olarak belirlediğiniz herhangi bir sınıfı geçirmek istediğinizde (mesela Integer nesnesi) ve bu nesne tipi üzerinde işlem yapmak istediğinizde, tahmin edebileceğiniz gibi Java derleyicisinin bu durumdan en ufak bir fikri yok. 9.5.2015 BLM202E Data Structures - 2015 Spring 6 Jenerikler (Java Generics) • Aşağıdaki program bir Box nesnesi oluşturur ve nesneye add metodu aracılığı ile bir Integer nesnesi geçirir. Daha sonra başka bir Integer nesnesine Box sınıfımıza geçirdiğimiz Integer nesnesini atayarak bu nesneyi ekrana bastırır. 9.5.2015 BLM202E Data Structures - 2015 Spring 7 Jenerikler (Java Generics) • Box nesnesinden dönen değeri Integer nesnemize atayıp programımızı sorunsuz bir şekilde çalıştırabiliyoruz. 9.5.2015 BLM202E Data Structures - 2015 Spring 8 Jenerikler (Java Generics) • Box nesnesinden dönen değerin Integer olduğunu garanti eden herhangi bir mekanizma var mı????????????? • Hatırlayın derleyicinin olan bitenden haberi yok, herhangi bir uyarı ya da hata vermeden kodu derleyecektir. 9.5.2015 BLM202E Data Structures - 2015 Spring 9 Jenerikler (Java Generics) • Aşağıdaki programda ise, Box nesnesine “10″ stringini geçirdik ve daha sonra Integer nesnemize Box nesnesine geçirdiğimiz String nesnemizi Integer tipine cast ederek atamaya çalıştık. 9.5.2015 BLM202E Data Structures - 2015 Spring 10 Jenerikler (Java Generics) • Kod sorunsuz bir şekilde derlenerek bytecode a çevirildi. Java derleyicisi herhangi bir uyarı vermeden kodumuzu derledi. Hatırlayın, Java derleyicisinin olan bitenden herhangi bir haberi yok. 9.5.2015 BLM202E Data Structures - 2015 Spring 11 Jenerikler (Java Generics) • Derleyiciye göre herşey normal bu durumda. Fakat bu kodu çalıştırdığımız zaman karşımıza • Exception in thread “main” java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at BoxDemo2.main(BoxDemo2.java:28) (Dongggggg ) • exceptionı gelecektir. Ancak çalışma zamanında (runtime) herhangi bir hata olup olmadığını anlayabildik. 9.5.2015 BLM202E Data Structures - 2015 Spring 12 Tamam Jenerikleri Kullanmam Gerek Ama Nasıl? • Şimdi Box sınıfımızı jenerikler kullanarak tekrar tasarlayalım. Kodu güncellerken yapmamız gereken ekleme “public class Box” sözdizimini “public class Box< T >” şekline getirmek., 9.5.2015 BLM202E Data Structures - 2015 Spring 13 Tamam Jenerikleri Kullanmam Gerek Ama Nasıl? • Burada yaptığımız işlem bir tip değişkeni belirlemek. Artık T adında bir tip değişkenimiz var ve bu tip değişkenini sınıfımızın içerisinde istediğimiz yerde kullanabiliriz. Sınıflar yanında bu tekniği Interfacelerde de kullanabiliriz. 9.5.2015 BLM202E Data Structures - 2015 Spring 14 Tamam Jenerikleri Kullanmam Gerek Ama Nasıl? • Burada vurgulanması gereken tek şey, oluşturduğumuz T tip değişkeni, sınıfımızın bir örneğini (instance) oluştururken, sınıfa geçirdiğimiz belirli bir nesne tipini simgelemesi. Aslında tamamen değişkenler ile yapılan işlemlerin aynısı. • Box sınıfımızı oluştururken “Box box = new Box();” şeklinde değil de “Box< Integer > box = new Box< Integer >();” şeklinde oluşturuyoruz. Bu sebeple T değişkenimiz artık “Integer” tipini simgeliyor ve sınıfımızda T tipini kullanarak yaptığımız tüm işlemler otomatik olarak “Integer” tipinde yapılıyor. 9.5.2015 BLM202E Data Structures - 2015 Spring 15 Tamam Jenerikleri Kullanmam Gerek Ama Nasıl? • Şimdi sınıfımız çok daha güvenli ve hatalara karşı çok daha dirençli. Herhangi bir yanlış atama karşısında hataları çok daha kolay bir şekilde yakalayabilecek durumdayız. • Şimdi test sınıfımızı da tekrar yazarak aradaki farklara bakalım. 9.5.2015 BLM202E Data Structures - 2015 Spring 16 Tamam Jenerikleri Kullanmam Gerek Ama Nasıl? • Artık Box nesnemizden dönen değeri hem biz hem de Java derleyicisi biliyor. Dönen değer “Integer” tipinde. Box nesnesinden dönen herhangi bir değeri farklı bir nesne tipine atama yapmaya çalışıldığında, Java derleyicisi buna izin vermeyecektir. Java, programcıların yaptıkları hataları en aza indirmek ve sağlam ve stabil uygulamalar hazırlamak için geliştirilmiş bir dildir. 9.5.2015 BLM202E Data Structures - 2015 Spring 17 Tamam Jenerikleri Kullanmam Gerek Ama Nasıl? • Ayrıca jenerik tipler tanımlanırken birden fazla tip değişkeni atanabilir. Örneğin “< T, U >” şeklinde bir tanımlama yapmak tamamı ile geçerlidir. Sınıf nesneleri oluşturulurken ilk verilen değer T ye, ikincisi U tipi ile değiştirilir. Yalnız, burada dikkat edilmesi gereken tek şey, aynı isme sahip tip değişkenleri bir arada kullanılamaz. Box< T, T > şeklinde bir atama yaptığınızda hata alırsınız. 9.5.2015 BLM202E Data Structures - 2015 Spring 18 •??? 9.5.2015 BLM202E Data Structures - 2015 Spring 19 Kaynaklar • [1] Data Structures and Algorithm Analysis in Java Mark A. Weiss 9.5.2015 BLM202E Data Structures - 2015 Spring 20