Üye Ol | Bağlan
ANASAYFA | VERİTABANI | PROGRAMLAMA | HAKKIMIZDA | BLOG | ETKİNLİKLER | KAYNAKLAR
Yazı Hakkında
  Yazar:Yahya ÖZTÜRK
Okunma: 1021
Oylanma:3 kişi (7,67/10)
 
 
YORUM EKLE

 
     
 
E-LİSTE
BT ve özellikle Veritabanı ile ilgili haber, yenilik ve etkinlikler hakkında önceden haber almak için bize e-mail adresinizi bırakabilirsiniz.

ANKET
SQL Server 2008'e geçtiniz mi?
Sorunsuz Geçtik
2005'e yeni geçtik
2000 bize yetiyor.
 
 



ANA SAYFA>

Java'da Yansıma Sınıfları

  

Bu makalede, derlenmiş kodlar içerisindeki yapılar ve tipler hakkında bilgi veren yansıma sınıflarının kullanımını inceleyeceğiz.

Giriş

Bu makalede Java içerisinde tanımlı olan yansıma sınıflarını inceleyeceğiz. Yansıma sınıfları ile sınıflar ile ilgili bilgiler alabilir sınıf metodlarını çağırabililiriz. Etkili bir kullanım ile kod satır sayımızı çok aşağılara çekebiliriz. Yazılımın bağımlılığını azaltıp yan etkilerden korunmuş koda sahip olabiliriz. Makalenin sonuna doğru bu sınıfları kullanarak bir basit uygulama geliştirip uygulama üzerinden konunun pekişmesini sağlayacağız.

Yansıma Sınıfları Nedir?

Yansıma sınıfları bize sınıflar(class) üzerinden bilgi almamıza yaran metodları içerir. Bu bilgiler ise şunladır;

  • Sınıf içerindeki tanımlı metodlar(methods)
  • Sınıf içerindeki tanımlı yapılandırıcılar(constructors)
  • Sınıf içerindeki tanımlı diğer sınıflar (classes)
  • Sınıf içerindeki tanımlı arayüzler (interfaces)
  • Sınıf içerindeki tanımlı değişkenler (variables)

Ayrıca reflection sınıfları bize şu dört önemli sınıfı da sunar

  • Method
  • Class
  • Field
  • Constructor

Bu sınıflar sayesinde istediğimiz bir sınıfın metoduna veya yapılandırıcısına veya değişkenlerine ulaşabiliriz. Aklımıza şu soru gelebilir zaten biz bunlara erişebiliyorduk ne işimize yarayacak bu sınıflar. Bu sorunuza şu senorya açıklık getirebilir sanıyorum.

Üç ayrı entityClass (Varlık sınıfları) olsun ve bu sınıfın öznitelikleri(attribute) bir HashTable içerisinde karışık olarak tutulsun. Siz bu varlık sınıflarının öznitelikleri atamak için tek tek get, put, set metodları kullanmak zorunda kalacaksınız. Bunun yerine şu şekilde bir çözümde muhtemeldir.

Sınıf ismini ve öznitelikleri tutan anahtar(key) sözcükleri bir isimlendirme formatından geçirdikten sonra sizin yazacağınız metod size şu işi yapabilir hale gelecek. Metod sizden sınıf ismini ve sınıfın bilgilerinin tutulduğu HashTable'yi isteyecek ve size direkt olarak öznitelikleri atanmış şekilde istediğiniz sınıfı dönecektir. Böylece 3 sınıf için yazacağınız kodu sadece bir kez yazarak çok genel bir metod yazmış olursunuz. Böylece programın bağımlılığı( dependence ) ve yan etkileri(side effect) azalır.

Bu örnek aklınızı karıştırdı ise bu senaryo daha anlışılır olacaktır.

Sizin bir sınıfınız var ve 15 tane değişkeni var. Siz bu değişkenlerin değerlerini tek tek atamak zorundasınız. Bunun yerine değişkenleri bir dizi içerise yerleştirip sadece bir kaç for döngüsü ile aynı işlemi yapabilirsiniz. Böylece hem daha düzgün bir kod yapısına ve daha az satır sayısına ulaşırsınız.

Methods Sınıfı

Bu sınıf metodlar ile alakalı bilgileri bize sağlar ve metodun çağrılmasına yardımcı olur.

Yararlı bir kaç metodu şunlardır

  • getName()
  • invoke
  • getReturnType()
  • getParameterTypes

geniş bilgi için www.java.sun.com adresi yardımcı olacaktır.

Class Sınıfı

Bu sınıf ise sınıflar hakkında bilgi almamıza yardımcı olur. Mesela metodlar, alanlar, yapılandırıcılar, arayüzler... Yansıma konusunun en önemli elemanıdır.

Constructure Sınıfı

Bu sınıf ise yapılandırıcılar hakkında bilgi verir. Yapılandırıcı adı, parametre listesi gibi. Yapılandırıcılarda bir metodtur fakat bu sınıfın bir invoke() metodu yoktur. Bunun yerine newInstance() metodu bulunur.

Field Sınıfı

Bu sınıf ise sınıflarda tanımlı olan alanların bilgilerini tutar ve bu bilgilere ulaşmamızı sağlar. En önemli metodları çevrim metodlarıdır. Bu nedenle kullanırken sizin çevrim(cast) yapmanıza gerek kalmayacaktır.

Ufak Bir Uygulama

Senaryo şu şekilde;

Bir varlık sınıfımız(entityClass) olacak bu sınıf oid, name, surname, address, eMail alanlarına sahip olacak. Her alan için getter ve setter oluşturacağız. Yani bir alana atama yapmak için setAlanAdy() metodunu alanın değerine ulaşmak için ise getAlanAdı() metodunu çağıracağız. Daha sonra metodların listesini alıp setName() motoduna gelince name alanını “yahya” yapacağız. Daha sonrada değişikliğin olduğunu görmek için ise getName() metoduna gelince alanın değerini ekrana yazdıracağız.

Buraya uygulamanın hepsini koymayacağım sadece önemli olan bölümlerini burada inceleyeceğiz.

public class ReflectionExample { 

private Class cls; 
private Method[] m; 
public ReflectionExample() 
{ 
setCls(ReflectionEntity.class); 
setM(cls.getMethods()); 
} 
public Class getCls() { 
return cls; 
} 
public void setCls(Class cls) { 
this.cls = cls; 
} 
public Method[] getM() { 
return m; 
} 
public void setM(Method[] m) { 
this.m = m; 
} 
} 

Bu sınıf iki alandan oluşuyor. Birisi Class tipinde, diğeri bir Method dizisi. Yapılandırıcısı ise Class tipindeki değişkene ReflectionEntity sınıfını Method dizisine ise bu sınıfın metodlarını atıyor.

public class ReflectionMain { 


public static void main(String[] args) { 

ReflectionExample rfexm = new ReflectionExample(); 
Class cls = rfexm.getCls(); 
Object[] objParam = new Object[1]; 
Object[] objParamNull = new Object[1]; 
Object objClass = null; 
objParam[0] = "yahya"; 
try { 
objClass = cls.newInstance(); 
} catch (InstantiationException e2) { 
e2.printStackTrace(); 
} catch (IllegalAccessException e2) { 
e2.printStackTrace(); 
} 
for(int i =0; i<rfexm.getM().length; i++) 
{ 
System.out.println(rfexm.getM()[i].getName()); 

if(rfexm.getM()[i].getName().equals("setName")) 
{ 
try { 
rfexm.getM()[i].invoke(objClass,objParam); 
} catch (IllegalArgumentException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
} catch (IllegalAccessException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
} catch (InvocationTargetException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
} 
} 
} 
} 

Bu bölümde ise ReflectionExample sınıfının bir örneğini aldık ve bu örnek üzerinden m Method dizisine ulaştık. Daha sonra yaptığımız ise metodların isimleri ekrana yazdırıyoruz ve setName() metoduna geldiğimizde ise bu metodu bir sınıf üzerinden çağırıyoruz.

invoke() metodu iki argüman alır ve ikiside Object türündendir. Bu argümanlardan birincisi metodu çağıracağımız sınıf diğeri ise metodun parametreleridir. Kodmuzda yaptığımız iş ise iki argümanı oluşturmak.

Class cls = ReflectionEntity.class; 
Object objClass = null; 
try { 
objClass = cls.newInstance(); 
} catch (InstantiationException e2) { 
e2.printStackTrace(); 
} catch (IllegalAccessException e2) { 
e2.printStackTrace(); 
} 

Yukarıdaki kod parçasına bakıldığında ilk argümanın hazırlanmasını görürüz. Class tipinde bir değişken tanımlayıp o değişkene hangi sınıf üzerinde işlem yapacaksan o sınıf atanır. Daha sonra ise gerekli olan Object türündeki değişkene bu sınıf atanır. Bu nasıl oldu diye düşünenler için bütün sınıfların Object türünden türedeğini hatırlatmak isterim.

Class cls = ReflectionEntity.class; 
Object[] objParam = new Object[1]; 
objParam[0] = "yahya"; 

Bu kod parçası ise metodun parametrelerinin nasıl oluşturulduğunu gösteriyor. Yapılacak işlem bir Object dizisi oluşturmak ve her parametrenin değerini object dizisinin içerisine yerleştirmek. Bizim örneğimiz için bir string gerekiyordu ve bizde dizinin 0. elemanına “yahya” stringini yerleştirdik.

Gerisi invoke() metodunu çağırmaktır.

Sonuç

Bu makalemizde Yansıma sınıflarına giriş yaptık. Tabiki sınıfların kullanımı bu kadarla sınırlı değil. Yaptığım uygulamanın kaynak kodunu buradan indirebilirsiniz.Sonraki makalemizde sınıfları biraz daha açıp daha gelişmiş uygulamalar üzerinde çalışacağız. Yeni makalede görüşmek dileği ile.

[18.08.2005]

Oy Ver: Kötü 1  2  3  4  5  6  7  8  9  10  İyi
Java‘da Tasarım Desenleri(Design Patterns) – 4 Java ile Nesneye Dayalı Programlama – 4
 
© 2003 - 2005 Verivizyon.com 'Developer Academy'. Tüm hakları saklıdır. Kullanım Sözleşmesi | Gizlilik İlkeleri | İletişim