Reflection API

Merhabalar, bu yazımda Java’daki Reflection API‘ye kısaca değineceğim. Reflection API, çalışma zamanı anında, metotların, sınıfların ve interface’lerin davranışlarını incelemek veya değiştirmek için kullanılır.

Reflection, bir nesnenin hangi sınıfa ait olduğu ve nesneye ait hangi metotların koşturulabileceği hakkında bilgiler verir ve bunu runtime anında yapar.

getClass() metoduyla nesnenin ait olduğu sınıfın ismine erişilebilir.
getConstructors() metoduyla nesnenin ait olduğu sınıfın public constructor‘larına erişilebilir.
getMethods() metoduyla nesnenin ait olduğu sınıfın public metodlarına erişilebilir.

Eğer bir sınıfın sahip olduğu private field‘lara veya metotlara erişmek istersek şu şekilde ilerleyebiliriz.
Class.getDeclaredField(FieldName) ile Field nesnesini aldıktan sonra Field.setAccessible(true) yaparak, access modifier‘ından bağımsız olarak metot veya field‘a erişim sağlanabilir.

Reflection‘lar sahip oldukları bu özellikleriyle bize genişletilebilirlik(Extensibility) anlamında avantajlar sağlamaktadır. Ancak bir nesnenin hangi sınıfa ait olduğu bilip Reflection API kullanmadan yapmak performans açısından daha iyidir. Bu nedenle sıklıkla kullanılan kodlarda Reflection API kullanılmasından kaçınılmalıdır. Ayrıca Reflection abstraction kavramını da yok etmeye meyillidir.

Yukarıda bahsettiklerimi basit olarak kodda aşağıdaki gibi uygulayabiliriz.

ReflectionTest.java

public class ReflectionTest {
    private String str;

    public ReflectionTest() {

    }

    public void method1() {
        System.out.println("Method 1 worked");
    }

    public void method2() {
        System.out.println("Method 2 worked");
    }

    public String getStr() {
        return str;
    }
}

Main.java

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {
    public static void main(String... args) throws
            NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
        ReflectionTest test = new ReflectionTest();
        Class clazz = test.getClass();
        System.out.println("test object class name : " + clazz.getName());
        System.out.println("test object class constructor name : "
                + clazz.getConstructor().getName());
        for (Method method: clazz.getMethods()) {
            System.out.println("Method Name : " + method.getName());
        }
        Method method1 = clazz.getMethod("method1");
        //calling method1
        method1.invoke(test);

        //private field accessing and set new value
        Field field = clazz.getDeclaredField("str");
        field.setAccessible(true);
        field.set(test, "TEST");
        System.out.println("str value : " + test.getStr());
    }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s