Reflection API এবং Generics একত্রিতভাবে জাভায় টাইপ ডাইনামিক্সের উপর আরো গভীর নিয়ন্ত্রণ এবং তথ্য পাওয়ার সুযোগ দেয়। Reflection ব্যবহার করে জেনেরিক ক্লাস, মেথড, এবং ফিল্ডের টাইপ ইনফরমেশন রানটাইমে অ্যাক্সেস করা যায়। এটি বিশেষত এমন ক্ষেত্রে দরকারী যেখানে জেনেরিক টাইপ সম্পর্কিত ডায়নামিক অপারেশন প্রয়োজন।
Generics এবং Type Erasure
জাভায় জেনেরিক্স টাইপ ইনফরমেশন Compile-Time-এ চেক করা হয় এবং Type Erasure এর মাধ্যমে রানটাইমে টাইপের তথ্য মুছে যায়। তবে, Reflection API ব্যবহার করে সীমিত কিছু ক্ষেত্রে এই টাইপ ইনফরমেশন রানটাইমে পুনরুদ্ধার করা সম্ভব।
Reflection API এর সাথে Generics এর Integration
1. Generic Class এর Type Parameters বের করা
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
class GenericClass<T> {
// Empty class
}
public class Main {
public static void main(String[] args) {
GenericClass<String> obj = new GenericClass<>();
Type superclass = obj.getClass().getGenericSuperclass();
if (superclass instanceof ParameterizedType) {
ParameterizedType parameterized = (ParameterizedType) superclass;
Type[] typeArgs = parameterized.getActualTypeArguments();
for (Type type : typeArgs) {
System.out.println("Type Argument: " + type.getTypeName());
}
} else {
System.out.println("No Parameterized Type found.");
}
}
}
আউটপুট:
No Parameterized Type found.
কারণ: রানটাইমে জাভা টাইপ মুছে ফেলে। Type Erasure এর কারণে এই উদাহরণটি সরাসরি কাজ করে না।
2. Generic Method এবং এর Parameter Types বের করা
import java.lang.reflect.Method;
import java.lang.reflect.Type;
public class GenericMethodExample {
public <T> void genericMethod(T param) {
System.out.println(param);
}
public static void main(String[] args) throws Exception {
Method method = GenericMethodExample.class.getMethod("genericMethod", Object.class);
System.out.println("Method Name: " + method.getName());
Type[] parameterTypes = method.getGenericParameterTypes();
for (Type type : parameterTypes) {
System.out.println("Parameter Type: " + type.getTypeName());
}
}
}
আউটপুট:
Method Name: genericMethod
Parameter Type: T
3. Generic Type Information সহ Collection Analysis
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
class GenericHolder {
public List<String> stringList;
}
public class Main {
public static void main(String[] args) throws NoSuchFieldException {
Field field = GenericHolder.class.getField("stringList");
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
for (Type arg : typeArguments) {
System.out.println("Generic Type Argument: " + arg.getTypeName());
}
}
}
}
আউটপুট:
Generic Type Argument: java.lang.String
Complex Example: Generic Class with Multiple Parameters
কোড:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
}
public class Main {
public static void main(String[] args) {
Pair<String, Integer> pair = new Pair<>("Age", 30);
Type superclass = pair.getClass().getGenericSuperclass();
if (superclass instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) superclass;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
System.out.println("Type Parameters:");
for (Type type : typeArguments) {
System.out.println(type.getTypeName());
}
}
}
}
আউটপুট:
Type Parameters:
java.lang.String
java.lang.Integer
Wildcard এবং Reflection
কোড:
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
class WildcardHolder {
public List<? extends Number> numbers;
}
public class Main {
public static void main(String[] args) throws NoSuchFieldException {
Field field = WildcardHolder.class.getField("numbers");
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
Type[] typeArguments = parameterizedType.getActualTypeArguments();
for (Type type : typeArguments) {
System.out.println("Wildcard Type: " + type.getTypeName());
}
}
}
আউটপুট:
Wildcard Type: ? extends java.lang.Number
Reflection এর সীমাবদ্ধতা
- Type Erasure: জাভা রানটাইমে টাইপ ইনফরমেশন মুছে ফেলে।
- Raw Type Handling: রো টাইপের ক্ষেত্রে নির্ভুল তথ্য পাওয়া যায় না।
- Performance Impact: Reflection ব্যবহারের ফলে পারফরম্যান্স কিছুটা কমতে পারে।
- Reflection API এর সাথে জেনেরিক্স ব্যবহার করলে রানটাইমে জেনেরিক টাইপ ইনফরমেশন পাওয়া সম্ভব।
- Type Erasure-এর কারণে কিছু সীমাবদ্ধতা রয়েছে।
- বড় প্রজেক্টে ডাইনামিক ডেটা হ্যান্ডলিং বা ফ্রেমওয়ার্ক তৈরি করার ক্ষেত্রে Reflection এবং Generics এর Integration অপরিহার্য।
Read more