Java Reflection bir uygulama geliştirme arayüzü olup, o anki Java Sanal Makinesindeki sınıfları, arayüzleri ve nesneleri yansıtan, temsil
Bir nesnenin sınıfını belirleriz
Sınıfın sahaları, metodları, yapıcıları, üst sınıfları ve değişkenleri hakkında bilgiler alabiliriz
Bir arayüze ait olan sabit ve metod tanımlamalarını tespit ederiz
Çalışma zamanına kadar ismi bilinmeyen bir sınıf örneği yaratabiliriz (Bir bakıma çalışma zamanında yeni sınıflar yaratabilirsiniz)
Çalışma zamanına kadar ismi bilinmese de sahaların değerini ayarlar ve alabiliriz.
Aynen çalışma zamanına kadar bilinmeyen metodları çalıştırabiliriz.
Çalışma zamanına kadar bileşenleri ve boyutu bilinmeyen diziler yaratabilir, daha sonra bu dizinin bileşenlerini değiştirebiliriz.
Çok önemli bir hatırlatma, standart java yapılarıyla yapabileceğiniz işleri Java yansıtma kütüphanesiyle yapmamalıyız. Umulmadık zorluklar ve sorunlarla karşılaşabiliriz.
Şimdi aşama aşama yansıtma kütüphanesini inceleyelim. Temel olarak yapmak istediğimiz ilk işlem bir nesnenin hangi sınıfa ait olduğunu bulmaktır. Sınıfı bulduktan sonra bu sınıf yardımıyla yansıtma kütüphanesinin tüm nimetlerinden faydalanabiliriz. Bunu yapmak için nesne.getClass() (Class döndürmektedir) çağrımında bulunuruz. Bu aldığımız Class tipinde nesneyi kullanarak nesnemizin metodlarını listeleyebilir, sahalarını listeleyebilir, istediğimiz sahanın get ve set metodlarını bulup çalıştırabiliriz.
Aşağıda çok basit bir, nesnenin tüm metodlarını ekrana yazdıran kodu görebilirsiniz:
import java.lang.reflect.*; //Bize gerekecek tum siniflar bu pakette
import java.util.ArrayList;
public class MetodYazdir {
public static void main(String[] args) {
try {
//Once ArrayList sinifinin Class nesnesini alalim
//getClass() metodu da kullanilabilir
Class c = ArrayList.class;
//Daha sonra bu sinif icerisindeki tum metodlari cekelim
Method[] m = c.getDeclaredMethods();
//Ve bu metod dizisini dolasarak bilgilerini ekrana yazalim
for (int i = 0; i <>
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
Bu kodu çalıştırdığınız zaman
public void java.util.ArrayList.add(int,java.lang.Object)
public boolean java.util.ArrayList.add(java.lang.Object)
public java.lang.Object java.util.ArrayList.clone()
…………………………………
Şeklinde uzayıp giden ve ArrayList sınıfının metodları erişim ve parametre bilgilerini gösteren çıktıyı göreceksiniz.
Bir yansıtma işlemi yapabilmek için temel olarak ilk yapılması gereken Class nesnesine ulaşmaktır. Bunun için farklı yöntemler vardır.
Class c = Class.forName("java.lang.String");
Class c = int.class;
Class c = Integer.TYPE;
Class c = Ogrenci.getClass();
Bu Class nesnesini aldıktan sonra bu nesne içerisindeki metodlar kullanılarak her türlü bilgi (sınıfla ilgili olan) rahatça alınabilir. Aşağıdaki bağları inceleyerek bu konuda hakkında daha ayrıntılı bilgilere ulaşabilirsiniz. Ayrıca örnek kodların (açıklamalı) içerisindeki ClassParser sınıfını her türlü projenizde ihtiyaçlarınız doğrultusunda kullanabiliriz.
Java.lang.reflect PAKETİ:
Class lar ve object ler hakkında yansıtıcı bilgi elde etmek için arayüzler ve sınıflar sağlar.
java.lang.reflect paketi tanımı
reflection(yansıma)yüklü olan class ların yapıcı fonksiyonları,alanları ,metotları hakkında bilgiye programlı erişim sağlar ve reflected(yansımış) alanları,metotları ve yapıcı fonksiyonları, nesnelerin temelindeki gizli kısıtlamalarıyla kopyaları üzerinde işlem yapar.
Bu paketteki sınıflar ,java.lang.Class beraberinde debuggers,interpreters,object inspectors,class browsers ve object serialization ve verilen bir sınıf tarafından tanımlanmış üyeler veya hedef nesnenin public üyelerine erişime ihtiyacı olan javabeans gibi servis uygulamalrını birleştirir.
Bir sınıfın metodları hakkında bilgilenmek;
import java.lang.reflect.*;
public class MetodBilgi {
//Bu ornek metodu ekrana basilmasini bekliyoruz
private int f1(Object p, int x)
throws NullPointerException {
if (p == null) {
throw new NullPointerException();
}
return x;
}
public static void main(String[] args) {
try {
//MetodBilgi sinifinin Class nesnesini alalim
Class cls = Class.forName("MetodBilgi");
//Metod dizisini cekelim
Method[] methlist = cls.getDeclaredMethods()
//Bu metod dizisini dolasalim
for (int i = 0; i <>
//Dizideki her metod icin ekrana
Method m = methlist[i];
//ismini
System.out.println("isim :"
+ m.getName());
//tanimlandigi sinif bilgisini
System.out.println("tanimlandigi sinif :"
+m.getDeclaringClass());
//Parametre bilgilerini
Class[] pvec = m.getParameterTypes();
for (int j = 0; j <>
System.out.println("parametre #" + j
+ " " + pvec[j]);
//Firlattigi istisna bilgilerini
Class[] evec = m.getExceptionTypes();
for (int j = 0; j <>
System.out.println("exception #"
+ j + " " + evec[j]);
//Metodun geri donus degerini
System.out.println("donus tipi = "
+ m.getReturnType());
//yazalim
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
Yapıcılar hakkında bilgilenmek;
import java.lang.reflect.*;
public class YapiciBilgi {
public YapiciBilgi() {
}
protected YapiciBilgi(int i, double d) {
}
public static void main(String[] args) {
try {
Class cls = Class.forName("YapiciBilgi");
//Bu sekilde bu sinif icerisinde tanimlanmis olan
//yapicilarin dizisini aliyoruz
Constructor[] ctorlist = cls.getDeclaredConstructors();
for (int i = 0; i <>
Constructor ct = ctorlist[i];
System.out.println("isim :"
+ ct.getName());
System.out.println("tanimlandigi sinif :"
+ct.getDeclaringClass());
Class[] pvec = ct.getParameterTypes();
for (int j = 0; j <>
System.out.println("parametre #"
+ j + " " + pvec[j]);
Class[] evec = ct.getExceptionTypes();
for (int j = 0; j <>
System.out.println("exception #"
+ j + " " + evec[j]);
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
Sahalar hakkında bilgilenmek;
import java.lang.reflect.*;
public class SahaBilgi {
public static final int i = 37;
private double d;
String s = "deneme";
public static void main(String[] args) {
try {
Class cls = Class.forName("SahaBilgi");
//Bu sekilde bu sinifin icerisinde tanimlanmis
//sahalarin dizisine erisiriz
Field[] fieldlist = cls.getDeclaredFields();
//Bu diziyi dolasiriz
for (int i = 0; i <>
//dizideki her eleman icin
Field fld = fieldlist[i];
//sahanin ismini
System.out.println("isim :"
+ fld.getName());
//tanimlandigi sinifi
System.out.println("tanimlandigi sinif :" +
fld.getDeclaringClass());
//tipini
System.out.println("tipi :"
+ fld.getType());
int mod = fld.getModifiers();
//ve resmi bir bicimde private,public,static,final v.b.
//erisim bilgilerini
System.out.println("modifier :"
+ Modifier.toString(mod));
//ekrana yazariz
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
İsmini kullanarak metodları çalıştırma;
import java.lang.reflect.*;
public class MetodCalistirma {
public int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
try {
//Sinifi alalim
Class cls = Class.forName("MetodCalistirma");
//Gonderecegimiz parametre tiplerini ayarliyoruz
Class[] partypes = new Class[2];
//Iki parametresi de Integer tipinde olan metod
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
//adi 'add' olan ve partypes parametre tiplerine sahip
//metodu aliyoruz
Method meth = cls.getMethod("add", partypes);
//Metodu uzerinde calistiracagimiz nesne ornegini
//yaratalim
MetodCalistirma methobj = new MetodCalistirma();
//Gonderecegimiz parametre listesini yaratalim
Object[] arglist = new Object[2];
//Parametreler Integer tipinde
//Birincisi 37 degerinde
arglist[0] = new Integer(37);
//Ikincisi 47 degerince
arglist[1] = new Integer(47);
//Daha sonra onceden bulmus oldugumuz metodu
//yarattigimiz methobj uzerinde arglist argumanlari
//ile calistiralim
Object retobj = meth.invoke(methobj, arglist);
//Donen degeri uygun tipe dondurur
Integer retval = (Integer) retobj;
//Ekrana yazalim Sonuc olacak 37+47=84 ekrana
//yazilacaktir
System.out.println(retval.intValue());
} catch (Throwable e) {
System.err.println(e);
}
}
}
Yeni nesneler yaratmak
import java.lang.reflect.*;
public class NesneYarat {
public NesneYarat() {
}
public NesneYarat(int a, int b) {
System.out.println("a = " + a + " b = " + b);
}
public static void main(String[] args) {
try {
Class cls = Class.forName("NesneYarat");
//Bulacagimiz yapici metodun parametre tiplerini
//ayarlayalim
Class[] partypes = new Class[2];
//Bulacagimiz yapici Integer tipinde iki
//parametre aliyor
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
//Yarattigimiz parametre tiplerini alan
//yapiciyi sinifta bulalim
Constructor ct = cls.getConstructor(partypes);
//Bu yapici calistirirken gonderecegimiz
//argumanlari yaratalim
Object[] arglist = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
//Ve bu argumanlari kullanarak bu yapiciyi
//calistiralim
//Yapici metodun calismasi sonunda elimizde
//NesneYarat tipinde bir ornek oldu
Object retobj = ct.newInstance(arglist);
//Ekrana bu olusan nesnenin basit sinif ismini
//(paket bilgisi olmadan) yazalim
System.out.println(retobj.getClass().getSimpleName());
} catch (Throwable e) {
System.err.println(e);
}
}
}
Saha değerini değiştirmek;
import java.lang.reflect.*;
public class DegerDegistirme {
public double d;
public static void main(String[] args) {
try {
Class cls = Class.forName("DegerDegistirme");
//Sinifin 'd' isimli sahasini alalim
Field fld = cls.getField("d");
//Deger degistirme uygulayacagimiz nesne ornegini
//yaratalim
DegerDegistirme f2obj = new DegerDegistirme();
//Sahanin degisimden onceki degerini ekrana basalim
System.out.println("d = " + f2obj.d);
//Degerini 12.34 ile degistirelim
//Eger tipini biliyorsak o tipe uygun set ve get
//metodlari kullanilarak sahalarin degerleri ayarlanir
//ve alinir
fld.setDouble(f2obj, 12.34);
//Ekrani degisimden sonraki degeri basalim
System.out.println("d = " + f2obj.d);
} catch (Throwable e) {
System.err.println(e);
}
}
}
Dizi kullanimi;
import java.lang.reflect.*;
public class Dizi {
public static void main(String[] args) {
try {
//String tipinde Class nesnesini olusturalim
Class cls = Class.forName("java.lang.String");
//Bu Class nesnesi tipinde 10 elemanli bir dizi olusturalim
Object arr = Array.newInstance(cls, 10);
//5. elemani "Bu bir deneme" seklinde ayarlayalim
Array.set(arr, 5, "Bu bir deneme");
//5. elemani cekelim
String s = (String) Array.get(arr, 5);
//Ekrana basalim
System.out.println(s);
} catch (Throwable e) {
System.err.println(e);
}
}
}
Daha karmaşık dizi örneği
import java.lang.reflect.*;
public class KarmasikDizi {
public static void main(String[] args) {
int[] dims = new int[] { 5, 10, 15 };
//Yukarida tanimladigimiz uzunluklarda 3 boyutlu dizi
//ornegi olusturalim
//Boyutlar sirasiyla 5,10 ve 15 uzunlugunda olacaktir
Object arr = Array.newInstance(Integer.TYPE, dims);
//Dizinin ucuncu elemanini alalim
Object arrobj = Array.get(arr, 3);
//Bu elemanin Class nesnesini alip
Class cls = arrobj.getClass();
//Ekrana tipini basalim (int[][])
System.out.println(cls.getSimpleName());
//Daha sonra ucuncu elemanin besinci elemanini
//alalim
arrobj = Array.get(arrobj, 5);
//Ve bu elemanin 10. elemanini 37 olarak
//ayarlayalim
Array.setInt(arrobj, 10, 37);
//Olusturdugumuz nesneyi tipine donusturup
int[][][] arrcast = (int[][][]) arr;
//Degistirdigimiz elemani ekrana yazalim
System.out.println(arrcast[3][5][10]);
}
}
Hiç yorum yok:
Yorum Gönder