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.
1. ClassLoader
2. Class.forName()
1. ClassLoader - Tam İsim ile Class'ı BulmakJava'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'ı Bulmak
Class.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
örnek
Class 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 SonraElimizde 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
Class.newInstance() will only succeed if the constructor is has zero arguments and is already accessible.
Yani
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.
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.
public 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;
}
2. Constructor.newInstance() metodu - Default Constructor Yoksa Kullanılabilir
Parametre Alan Constructor Örneği 1
Parametre alan constructor'a sahip bir nesne yaratmak için
örnekimport 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;
}
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");