Giriş
Java'da reflection ile nesne yaratmak için bir şekilde Class sınıfına erişip ya newInstance() metodu çağrılıyor ya da Class sınıfı aracılığıyla Constructor nesnesi bulunup nesne yaratılıyor.
Class Nasıl Bulunur ?
2 yöntem var.
Java'da reflection ile nesne yaratmak için bir şekilde Class sınıfına erişip ya newInstance() metodu çağrılıyor ya da Class sınıfı aracılığıyla Constructor nesnesi bulunup nesne yaratılıyor.
Class Nasıl Bulunur ?
2 yöntem var.
1. ClassLoader
2. Class.forName()
1. ClassLoader - Tam İsim ile Class'ı Bulmak
Java'da Class ve ClassLoader ile sınıfları yükleyip yaratabilmek mümkün. ClassLoader'ı kullanmaya hiç ihtiyaç duymadım. Her class kendisini yükleyen ClassLoader'ı bilir.
Class.forName() sadece class ve interface'ler için çalışır. bool gibi primitive tipler ile denersek ClassNotFounException alırız.
Class veya Constructor Bulunduktan Sonra
1. ClassLoader - Tam İsim ile Class'ı Bulmak
Java'da Class ve ClassLoader ile sınıfları yükleyip yaratabilmek mümkün. ClassLoader'ı kullanmaya hiç ihtiyaç duymadım. Her class kendisini yükleyen ClassLoader'ı bilir.
ClassLoader cl = t.getClass().getClassLoader();
ClassLoader arayüzünü gerçekleştiren sınıflardan birisi olan URLClassLoader aşağıdaki gibi yaratılabilir.
File file = new File("vendorcatalogapi.jar");
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
Daha sonra ClassLoader loadClass() metodu ile Class nesnesini verir.Class theClass = ClassLoader.loadClass("com.mycompany.SomeImpl");
2. Class.forName - Tam İsim ile Class'ı BulmakClass.forName() sadece class ve interface'ler için çalışır. bool gibi primitive tipler ile denersek ClassNotFounException alırız.
try {
Class.forName( "bool" );
}
catch( ClassNotFoundException e ) {
...
}
Tam sınıf ismi kullanan basit bir örnekClass theClass = Class.forName("com.example.Foo");
Eğer sınıfı yüklemek istemiyor sadece var olup olmadığını öğrenmek istiyorsak şöyle yaparız.Class.forName("com.example.Foo",
false,
ClassLoader.getSystemClassLoader());
İkinci parametrenin false olması sınıfın yüklenmesini engeller. Sınıfın static constructor metodu varsa çalışmadığını görürürüz.public class Foo {
static {
System.out.println("foo loaded and initialized");
}
}
Sınıf yoksa ClassNotFoundException alacağımız için, sınıfı yüklemeden varlığını tespit edebiliriz.Class veya Constructor Bulunduktan Sonra
Elimizde iki seçenek var.
1. Class sınıfının sunduğu newInstance metodunu kullanmak
2. Constructor sınıfının sunduğu newInstance metodunu kullanmak. Açıklaması şöyle
1. Class.newInstance metodu
Class bir kere bulunduktan sonra şu kurallara uyuyorsa yeni bir nesne yaratmak çok kolay
1. Sınıfın default constructor'a sahip olması gerekir.
2. Constructor'ın erişilebilir olması gerekir. Örneğin public olması gerekir.
Parametre Alan Constructor Örneği 1
Parametre alan constructor'a sahip bir nesne yaratmak için örnek
Class bir kere bulunduktan sonra şu kurallara uyuyorsa yeni bir nesne yaratmak çok kolay
YaniClass.newInstance() will only succeed if the constructor is has zero arguments and is already accessible.
1. Sınıfın default constructor'a sahip olması gerekir.
2. Constructor'ın erişilebilir olması gerekir. Örneğin public olması gerekir.
Eğer hata olursa bu metod IllegalAccessException ve InstantiationException atar.
Basit bir örnek
SomeImpl impl = (SomeImpl)theClass.newInstance();
Generic Örnek
Exceptionlardan kurtulup generic bir metod kullanmak istersek aşağıdaki gibi yapabiliriz. Örnekte Parent sınıfından kalıtan sınıflar yaratılıyor. Ayrıca Java 7 ile gelen çoklu exception yakalama da gösteriliyor.
2. Constructor.newInstance() metodu - Default Constructor Yoksa Kullanılabilirpublic static <T extends Parent> T load(Class<T> clazz) {
try {
T object = clazz.newInstance();
return object;
} catch (IllegalAccessException | InstantiationException e) {
//handle the exception here...
}
return null;
}
Parametre Alan Constructor Örneği 1
Parametre alan constructor'a sahip bir nesne yaratmak için örnek
import java.lang.reflect.Constructor;
...
Class<?> loadedClass = classLoader.loadClass("tmp."+className);
try {
Constructor<?> ctor=loadedClass.getConstructor(int.class);
ctor.newInstance(42);
...
}
Parametre Alan Constructor Örneği 2
Bu sefer Constructor nesnesi getConstructor ile değil, getDeclaredConstructor ile bulunuyor. Elimizde şöyle bir sınıf olsun.
public Person() {
}
public Person(int age) {
this.age = age;
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
Şöyle yaparız.
Class<Person> pClass = Person.class;
pClass.getDeclaredConstructor().newInstance(); // default constructor
pClass.getDeclaredConstructor(int.class).newInstance(50);
pClass.getDeclaredConstructor(int.class, String.class).newInstance(50, "test");