Yansıma, sınıfların, nesnelerin, yöntemlerin ve alanların yapısını ve davranışını programın çalışması sırasında araştırma ve değiştirme mekanizmasıdır. java.lang.reflect paketi aracılığıyla gerçekleştirilir.
Şunları sağlar:
Örnek:
import java.lang.reflect.Method; public class ReflectionExample { public void greet() { System.out.println("Merhaba!"); } public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("ReflectionExample"); Object instance = clazz.getDeclaredConstructor().newInstance(); Method method = clazz.getMethod("greet"); method.invoke(instance); // Çıktı: Merhaba! } }
Artıları:
Eksileri/Riskleri:
Yansıma aracılığıyla bir sınıfın özel alanlarına ve yöntemlerine erişim sağlanabilir mi ve bunun sonuçları nelerdir?
Cevap: Evet, Field veya Method üzerindeki setAccessible(true) yöntemi ile mümkündür:
Field field = clazz.getDeclaredField("privateField"); field.setAccessible(true); field.set(obj, "value");
Bu durum sınıfın kapsüllemesini ihlal eder ve risk taşır: durum hassas hale gelir, güvenlik hataları oluşabilir ve yeni JVM sürümlerinde bu tür işlemler erişim politikalarıyla kısıtlanabilir.
Hikaye
Büyük bir projede DTO'ları otomatik eşlemek için yansıma aracılığıyla "Optional" türündeki alanlar düzgün bir şekilde dikkate alınmamış, bu da veri toplu işleme sırasında NullPointerException'a yol açmıştır çünkü yansıma paketi Optional değerlerini ve null'ı ayırt edememiştir.
Hikaye
Bankacılık yazılımında, serileştirme için setAccessible(true) aracılığıyla özel alanlara erişim sağlanmıştır. JVM güncellendikten sonra davranış değişmiş, özel alanın erişimi kapatılmış, serileştirmenin önemli işlevi aniden üretim ortamında çalışmaz hale gelmiştir.
Hikaye
ORM frameworkünde proxy nesneleri oluştururken veri yapısının değişimi sonrası yansıma önbelleğini güncellemeyi unuttum. Sonuç olarak, sistem yeni sınıf alanları ile çalışırken öngörülemeyen hatalar vermiştir, bu alanlar önbellekte yer almıyordu.