Java Reflection API: බලසම්පන්න මෘදුකාංග සංවර්ධනයට Sinhala Guide

Java Reflection API: Java වල හංගපු බලේ එලියට ගමු! SC Guide
ආයුබෝවන්! කොහොමද ඉතින් කට්ටියට? අද අපි කතා කරන්න යන්නේ Java Programming වල තියෙන මරුම concept එකක් ගැන – ඒ තමයි Java Reflection API එක. මේක කියන්නේ Java වල අර ගහට මුවා වෙලා හංගපු, එළියට නොපෙනෙන මහා බලයක් වගේ දෙයක්. මම දන්නවා, මේක ටිකක් advanced topic එකක්, ඒත් හරියට තේරුම් ගත්තොත් ඔයාට Java වලින් කරන්න පුළුවන් දේවල් අනිවාර්යයෙන්ම තව ලෙවල් එකකට අරන් යන්න පුළුවන්.
දැන් ඔයාට හිතෙයි මොකක්ද මේ Reflection කියන්නේ කියලා? සරලව කිව්වොත්, Reflection කියන්නේ අපිට Program එකක් run වෙන වෙලාවෙදී (runtime) ඒ Program එකේ Class, Method, Field, Constructor වගේ හැමදෙයක්ම examine කරන්න (බලන්න), manipulate කරන්න (වෙනස් කරන්න) වගේම ඒවට අලුතෙන් value දෙන්න පුළුවන් හැකියාව. සාමාන්යයෙන් අපි Java වලින් code කරනකොට Program එක compile වෙන වෙලාවේ (compile time) තමයි ඔය හැමදේම තීරණය වෙන්නේ. ඒත් Reflection වලින් අපිට ඒ නීති ටික පොඩ්ඩකට පැත්තකට දාලා, වැඩේ තව ටිකක් dynamic කරන්න පුළුවන් වෙනවා.
ඉතින්, මේක මොනවටද වැඩියෙන්ම වැදගත් වෙන්නේ? Framework හදන අයට, IDE (Integrated Development Environment) develop කරන අයට, debugging tools හදන අයට වගේම generic code ලියන්න ඕනෙ අයට Reflection කියන්නේ අත්යවශ්ය දෙයක්. ඒ වගේම ඔයා Spring, Hibernate, JUnit වගේ framework පාවිච්චි කරනවා නම්, ඒවා ඇතුළේ වැඩ කරන්නේ මේ Reflection API එක පාවිච්චි කරලා තමයි. හරි එහෙනම්, අපි වැඩි කතා නැතුව බලමු මේක මොකක්ද, කොහොමද වැඩ කරන්නේ කියලා.
1. Reflection API කියන්නේ මොකක්ද මේ? (What is Reflection API?)
Java Reflection API එක තියෙන්නේ Java Platform, Standard Edition (Java SE) වල. මේක අපිට පුළුවන් කරනවා Program එකක් run වෙන වෙලාවේදී (runtime) Class, Method, Field, Constructor වගේ දේවල් ගැන තොරතුරු දැනගන්න වගේම ඒවට access කරන්න. සාමාන්යයෙන් අපි code ලියනකොට Class එකක method එකක් call කරනවා නම්, ඒ method එකේ නම compile වෙලාවේම අපි දන්නවානේ. හැබැයි Reflection පාවිච්චි කරලා අපිට පුළුවන් method එකේ නම string එකක් විදියට දීලා, ඒ method එක call කරන්න. මරු වැඩක් නේද?
මීට අමතරව, අපිට පුළුවන් Class එකක private fields වලට වුණත් access කරන්න, ඒවයේ values වෙනස් කරන්න. මේක ටිකක් භයානකයි වගේ පේනවා නේද? ඇත්තටම භයානකයි තමයි, මොකද මේකෙන් encapsulation rules ටික කැඩෙනවා. ඒත් සමහර වෙලාවට මේක නැතුවම බෑ. ඒ නිසා, මේක පාවිච්චි කරනකොට පරිස්සමින් පාවිච්චි කරන්න ඕනේ.
2. Reflection වලට පාවිච්චි වෙන ප්රධාන Classes ටික (Key Classes for Reflection)
Reflection API එකේ ප්රධාන Classes කිහිපයක් තියෙනවා. මේ ටික තමයි වැඩියෙන්ම පාවිච්චි වෙන්නේ:
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Field
java.lang.reflect.Constructor
අපි එකින් එක බලමු මේවා මොනවද කියලා:
2.1. Class Class එක (The java.lang.Class
)
Java වල හැම object එකක්ම, හැම array එකක්ම, හැම primitive type එකක්ම (int, boolean වගේ) compile වෙලාවේදී Representation වෙන්නේ Class object එකකින්. මේ Class object එකෙන් තමයි අදාල Class එකේ structure එක, methods, fields, constructors වගේ දේවල් ගැන තොරතුරු තියෙන්නේ.
Class object එකක් ගන්න ක්රම කීපයක් තියෙනවා:
Object.getClass()
: object එකක Class එක ගන්න.ClassName.class
: Class එකේ නම දන්නවා නම්.Class.forName("fully.qualified.ClassName")
: Class එකේ නම String එකක් විදියට දෙනකොට.
පොඩි උදාහරණයක් බලමු:
import java.lang.reflect.Method;
class SampleClass {
public void sayHello() {
System.out.println("Hello from SampleClass!");
}
private int calculateSum(int a, int b) {
return a + b;
}
}
public class ClassExample {
public static void main(String[] args) throws NoSuchMethodException {
// 1. Using object.getClass()
SampleClass obj = new SampleClass();
Class<?> class1 = obj.getClass();
System.out.println("Class from object: " + class1.getName());
// 2. Using ClassName.class
Class<?> class2 = SampleClass.class;
System.out.println("Class from .class literal: " + class2.getName());
// 3. Using Class.forName()
try {
Class<?> class3 = Class.forName("SampleClass");
System.out.println("Class from forName(): " + class3.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// Getting methods of the class
System.out.println("\nMethods of SampleClass:");
Method[] methods = class1.getDeclaredMethods(); // Includes private methods
for (Method method : methods) {
System.out.println(" Method Name: " + method.getName() + ", Return Type: " + method.getReturnType().getName());
}
}
}
මේ code එක run කරාම, SampleClass
එකේ තියෙන method ටික (sayHello
, calculateSum
) අපිට print කරගන්න පුළුවන් වෙනවා.
2.2. Method Class එක (The java.lang.reflect.Method
)
Method object එකකින් Class එකක තියෙන එක් method එකක් නියෝජනය වෙනවා. මේකෙන් අපිට පුළුවන් method එකේ නම, return type එක, parameters, modifiers (public, private වගේ) වගේ දේවල් දැනගන්න. ඒ වගේම, අපිට පුළුවන් invoke()
method එක පාවිච්චි කරලා, dynamic විදියට method එකක් call කරන්න.
import java.lang.reflect.Method;
class MyCalculator {
public int add(int a, int b) {
return a + b;
}
public String greet(String name) {
return "Hello, " + name + "!";
}
}
public class MethodExample {
public static void main(String[] args) throws Exception {
MyCalculator calc = new MyCalculator();
Class<?> calcClass = calc.getClass();
// Get the 'add' method
Method addMethod = calcClass.getMethod("add", int.class, int.class);
System.out.println("Method Name: " + addMethod.getName());
System.out.println("Return Type: " + addMethod.getReturnType().getName());
// Invoke the 'add' method dynamically
Object result = addMethod.invoke(calc, 5, 3);
System.out.println("Result of add(5, 3): " + result);
// Get the 'greet' method
Method greetMethod = calcClass.getMethod("greet", String.class);
Object greeting = greetMethod.invoke(calc, "Amal");
System.out.println("Result of greet(\"Amal\"): " + greeting);
}
}
මේකේ බලන්න, අපි method එකේ නම string එකක් විදියට දීලා, ඒක call කරන හැටි. මේකෙන් තමයි framework වල dynamic method execution කරන්නේ.
2.3. Field Class එක (The java.lang.reflect.Field
)
Field object එකකින් Class එකක තියෙන එක් field එකක් (variable එකක්) නියෝජනය වෙනවා. මේකෙන් අපිට පුළුවන් field එකේ නම, type එක, modifiers වගේ දේවල් දැනගන්න. ඒ වගේම, අපිට පුළුවන් get()
සහ set()
method පාවිච්චි කරලා, field එකක value එක ගන්න වගේම අලුත් value එකක් දෙන්නත් පුළුවන්.
import java.lang.reflect.Field;
class Person {
private String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
}
public class FieldExample {
public static void main(String[] args) throws Exception {
Person person = new Person("Kamal", 30);
Class<?> personClass = person.getClass();
// Accessing a public field
Field ageField = personClass.getField("age");
System.out.println("Public field name: " + ageField.getName());
System.out.println("Current age: " + ageField.get(person));
ageField.set(person, 31); // Change public field value
System.out.println("New age: " + ageField.get(person));
// Accessing a private field (Important!)
Field nameField = personClass.getDeclaredField("name");
nameField.setAccessible(true); // Allow access to private field
System.out.println("Private field name: " + nameField.getName());
System.out.println("Current name: " + nameField.get(person));
nameField.set(person, "Sunil"); // Change private field value
System.out.println("New name: " + nameField.get(person));
System.out.println("Name via getter: " + person.getName());
}
}
මේකේ බලන්න, private field එකකට access කරන හැටි. setAccessible(true)
කියන method එක තමයි magic එක කරන්නේ. මේකෙන් Java Security Manager එක bypass කරන්න පුළුවන්. ඒක නිසා පරිස්සමින් පාවිච්චි කරන්න ඕනේ!
3. මේකෙන් කරන්න පුළුවන් මොනවද? (Practical Use Cases)
Reflection API එකේ practical use cases ටිකක් බලමු:
Generic Code:
විවිධ types වල data handle කරන්න පුළුවන් generic utility methods හදන්නත් Reflection පාවිච්චි කරන්න පුළුවන්. උදාහරණයක් විදියට, ඕනෑම object එකක හැම field එකම print කරන method එකක් වගේ.
IDE Tools and Debuggers:
ඔයාගේ IntelliJ IDEA, Eclipse වගේ IDE එකක code completion, refactoring, debugging tools වලටත් Reflection තමයි පාවිච්චි කරන්නේ.
Serialization and Deserialization:
JSON, XML වගේ format වලට object convert කරනකොට (e.g., Jackson, GSON libraries), ඒක Class එකේ fields identify කරලා, ඒවට values set කරන්න Reflection පාවිච්චි කරනවා.
Dynamic Proxy Objects:
Runtime එකේදී Interfaces implement කරන proxy objects හදන්නත් Reflection පාවිච්චි කරනවා. AOP (Aspect-Oriented Programming) වගේ දේවල් වලට මේක ගොඩක් වැදගත්.
Frameworks and Libraries:
Spring, Hibernate, JUnit වගේ framework වල dependency injection, ORM (Object-Relational Mapping), test automation වගේ දේවල් වලට Reflection බහුලව පාවිච්චි කරනවා. උදාහරණයක් විදියට, Spring Framework එකේ @Autowired
annotation එකෙන් dependency injection කරනකොට, ඒක field එක identify කරලා, ඒකට අදාල object එක inject කරන්න Reflection පාවිච්චි කරනවා.
4. හොඳ සහ නරක (Pros and Cons)
හැමදෙකම වගේ Reflection API එකටත් හොඳ පැති වගේම, පොඩි නරක පැතිත් තියෙනවා. අපි ඒ ටිකත් බලමු.
හොඳ පැති (Pros):
- Flexibility and Extensibility: Program එකේ behavior එක runtime එකේදී වෙනස් කරන්න පුළුවන්. Framework හදන අයට මේකෙන් අති විශාල flexibility එකක් ලැබෙනවා.
- Reduced Boilerplate Code: සමහර වෙලාවට අපිට එකම විදියේ code ගොඩක් ලියන්න වෙනවා නම් (e.g., getters/setters), Reflection පාවිච්චි කරලා ඒ code ප්රමාණය අඩු කරගන්න පුළුවන්.
- Framework Development: Spring, Hibernate වගේ දියුණු framework හැදෙන්න ප්රධාන හේතුවක් තමයි Reflection.
- Dynamic Applications: compile-time එකේදී නොදන්න classes, methods වගේ දේවල් එක්ක වැඩ කරන්න පුළුවන්.
නරක පැති (Cons):
- Performance Overhead: Reflection සාමාන්ය method calls වලට වඩා සෑහෙන slow. මොකද runtime එකේදී Class information lookup කරන්න වෙන නිසා. High-performance application වල මේක ගැටලුවක් වෙන්න පුළුවන්.
- Security Risks:
setAccessible(true)
වගේ method පාවිච්චි කරලා private fields/methods වලට access කරන්න පුළුවන් නිසා, encapsulation rules කැඩෙනවා. මේක security vulnerabilities ඇති කරන්න පුළුවන්. - Reduced Type Safety: Compile-time checks නැති නිසා, runtime එකේදී
NoSuchMethodException
,IllegalAccessException
වගේ exceptions එන්න පුළුවන්. - Code Complexity: Reflection code සාමාන්ය code වලට වඩා කියවන්න සහ maintain කරන්න අමාරුයි.
- Platform Restrictions: සමහර Java runtime environment වල (e.g., Android), Reflection usage වලට restrictions තියෙන්න පුළුවන්.
අවසන් වශයෙන් (Conclusion)
Java Reflection API එක කියන්නේ Java වල තියෙන බලසම්පන්නම features වලින් එකක්. මේක අපිට අපේ program වලට අමතර flexibility එකක් වගේම dynamic behavior එකක් දෙන්න උදව් වෙනවා. Frameworks, libraries, tooling වගේ දේවල් වලදී මේක අතිශයින්ම වැදගත්. හැබැයි, මේක පාවිච්චි කරනකොට performance impact, security risks, code complexity වගේ දේවල් ගැනත් සැලකිලිමත් වෙන්න ඕනේ.
මම හිතනවා මේ article එකෙන් ඔයාලට Java Reflection API එක ගැන හොඳ අවබෝධයක් ලැබෙන්න ඇති කියලා. දැන් ඔයාලත් මේක පොඩ්ඩක් පාවිච්චි කරලා බලන්න. පොඩි පොඩි program ලියලා experiment කරලා බලන්න. එතකොට මේකේ බලය සහ සීමාවන් ඔයාලටම තේරෙයි. මොකද, theory දැනගන්නවාට වඩා practice කරන එක ගොඩක් වැදගත්.
ඔයාලගේ අදහස්, ප්රශ්න, නැත්නම් ඔයාල Reflection පාවිච්චි කරපු interesting use cases තියෙනවා නම්, පහලින් comment එකක් දාගෙන යන්න අමතක කරන්න එපා. අපි තව අලුත් article එකකින් හම්බෙමු එහෙනම්! Happy Coding!