জাভার Generics এর একটি গুরুত্বপূর্ণ বৈশিষ্ট্য হলো Type Erasure। এটি জেনেরিক্সের কাজ করার পদ্ধতিকে ব্যাখ্যা করে। Type Erasure হলো একটি প্রক্রিয়া যা কম্পাইল টাইমে জেনেরিক্স সম্পর্কিত টাইপ চেকিং নিশ্চিত করে এবং রানটাইমে জেনেরিক্স টাইপের তথ্য মুছে ফেলে।
Type Erasure কি?
- Type Erasure হল একটি প্রক্রিয়া যেখানে জেনেরিক্স টাইপের তথ্য রানটাইমে সরিয়ে ফেলা হয়।
- জাভার কম্পাইলার Generics ব্যবহার করে টাইপ চেকিং করে এবং রানটাইমে জেনেরিক্সকে Raw Type-এ রূপান্তরিত করে।
- এটি জাভার Backward Compatibility বজায় রাখার জন্য করা হয়েছে, যাতে জেনেরিক্স ছাড়াই পুরোনো কোড Generics ব্যবহারকারী নতুন কোডের সাথে কাজ করতে পারে।
Type Erasure এর কাজ করার পদ্ধতি:
- Type Checking এবং Replacing:
- কম্পাইল টাইমে জেনেরিক্স টাইপ চেকিং করা হয়।
- জেনেরিক টাইপটি Raw Type (e.g.,
List<T>->List) এ রূপান্তরিত হয়। - যদি টাইপ প্যারামিটারটি Bounded Type থাকে, তবে এটি সেই বাউন্ড টাইপের সাথে প্রতিস্থাপিত হয়।
- Bridge Methods যোগ করা:
কম্পাইলার অটো-জেনারেটেড মেথড তৈরি করে যাতে জেনেরিক্স এবং নন-জেনেরিক কোডের মধ্যে সামঞ্জস্য থাকে।
উদাহরণ:
১. Type Erasure এর Basic উদাহরণ:
public class GenericExample<T> {
private T data;
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
কম্পাইল করার পরে:
কম্পাইলারের Type Erasure এর কারণে এটি নিম্নরূপে রূপান্তরিত হয়:
public class GenericExample {
private Object data;
public void setData(Object data) {
this.data = data;
}
public Object getData() {
return data;
}
}
২. Bounded Type Parameters এর ক্ষেত্রে:
public class GenericExample<T extends Number> {
private T data;
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
কম্পাইল করার পরে:
public class GenericExample {
private Number data;
public void setData(Number data) {
this.data = data;
}
public Number getData() {
return data;
}
}
Type Erasure এর প্রভাব:
১. রানটাইমে টাইপ ইনফরমেশন অনুপস্থিত:
Generics টাইপ রানটাইমে মুছে ফেলা হয়। তাই নিম্নোক্ত উদাহরণটি কাজ করবে না:
public class Main {
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
System.out.println(stringList.getClass() == intList.getClass()); // true
}
}
আউটপুট:
true
কারণ
List<String>এবংList<Integer>রানটাইমেListএ রূপান্তরিত হয়।
২. Overloading এর সীমাবদ্ধতা:
Generics এর কারণে Overloading সম্ভব নয়, কারণ Type Erasure এর পরে একই সিগনেচার থেকে যায়।
public class Main {
public void method(List<String> list) {}
public void method(List<Integer> list) {} // কম্পাইল টাইম ত্রুটি
}
কম্পাইল টাইম ত্রুটি:
method(List<String>) এবং method(List<Integer>) এর signature একই।
Generics এর Type Erasure প্রভাবিত সীমাবদ্ধতা:
১. প্রিমিটিভ টাইপ সরাসরি ব্যবহার করা যায় না:
Generics এ প্রিমিটিভ টাইপ (e.g., int, double) সরাসরি ব্যবহার করা যায় না। এটি Autoboxing এর মাধ্যমে কাজ করে।
List<int> intList = new ArrayList<>(); // কম্পাইল টাইম ত্রুটি
List<Integer> intList = new ArrayList<>(); // সঠিক
২. রানটাইম টাইপ চেকিং সম্ভব নয়:
Generics টাইপ মুছে ফেলার কারণে নিম্নলিখিত কাজ সম্ভব নয়:
public void method(List<String> list) {
if (list instanceof ArrayList<String>) { // কম্পাইল টাইম ত্রুটি
// কিছু কাজ
}
}
৩. Generic Arrays তৈরি করা যায় না:
Generics Type Erasure এর কারণে জেনেরিক অ্যারে তৈরি করা যায় না।
List<String>[] listArray = new ArrayList<String>[10]; // কম্পাইল টাইম ত্রুটি
Generics এবং Raw Types:
Generics চালু হওয়ার আগে Collections Framework এ Raw Types ব্যবহৃত হতো। Generics এর মাধ্যমে টাইপ সেফটি নিশ্চিত হয়েছে, তবে Raw Types এখনও ব্যাকওয়ার্ড কম্প্যাটিবিলিটির জন্য সমর্থিত।
List list = new ArrayList(); // Raw Type
list.add("String");
list.add(123); // টাইপ সেফ নয়
Type Erasure Generics এর একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা জাভার ব্যাকওয়ার্ড কম্প্যাটিবিলিটি বজায় রাখে। তবে এর কিছু সীমাবদ্ধতাও রয়েছে, যেমন টাইপ চেকিং শুধুমাত্র কম্পাইল টাইমে ঘটে এবং রানটাইমে টাইপ ইনফরমেশন অনুপস্থিত। তবুও, Generics ব্যবহার করলে টাইপ সেফ কোড এবং পুনঃব্যবহারযোগ্য ডেটা স্ট্রাকচার তৈরি করা সহজ হয়।
Type Erasure হল একটি প্রক্রিয়া যা জাভা কম্পাইলার Generics-এর সাথে কাজ করার সময় ব্যবহার করে। Generics টাইপ প্যারামিটারগুলো compile-time এ চেক করা হয় এবং তারপর runtime এ Generics-এর তথ্য মুছে (erase) ফেলা হয়। এর ফলে জাভার JVM runtime এ Generics সম্পর্কে কোনো তথ্য সংরক্ষণ করে না।
কিভাবে Type Erasure কাজ করে?
Java-এর Generics backward compatibility নিশ্চিত করার জন্য Type Erasure ব্যবহার করে। Generics যোগ করার পরেও পুরনো কোড (pre-Java 5) এবং নতুন কোড একসাথে কাজ করতে পারে।
Type Erasure কাজ করে নিচের ধাপে:
- Compile-time এ টাইপ চেকিং নিশ্চিত করা:
Generics টাইপ প্যারামিটার compile-time এ চেক করা হয়, যাতে টাইপ সেফটি বজায় থাকে। - Runtime এ Generics মুছে ফেলা:
Compile-time এ Generics-এর সমস্ত টাইপ প্যারামিটার তাদের উপযুক্ত বাউন্ড (যদি নির্দিষ্ট করা হয়) বাObject-এ প্রতিস্থাপন করা হয়।
Type Erasure উদাহরণ
Generics Class Example
public class GenericClass<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
// Usage:
GenericClass<String> obj = new GenericClass<>();
obj.setValue("Hello");
System.out.println(obj.getValue());
Type Erasure এর পরে:
public class GenericClass {
private Object value;
public void setValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
}
Generics Method Example
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
// Usage:
String[] stringArray = {"A", "B", "C"};
printArray(stringArray);
Type Erasure এর পরে:
public static void printArray(Object[] array) {
for (Object element : array) {
System.out.println(element);
}
}
Bounded Type Parameters এবং Type Erasure
Generics-এ যদি বাউন্ড নির্ধারণ করা হয় (যেমন T extends Number), তবে টাইপ প্যারামিটারটি তার বাউন্ডের ক্লাস বা ইন্টারফেস-এ প্রতিস্থাপিত হয়।
উদাহরণ:
public class BoundedClass<T extends Number> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
Type Erasure এর পরে:
public class BoundedClass {
private Number value;
public void setValue(Number value) {
this.value = value;
}
public Number getValue() {
return value;
}
}
Type Erasure এর সুবিধা
- Backward Compatibility:
Type Erasure এর ফলে Generics-এর আগে তৈরি কোডের সাথে নতুন Generics কোড একসাথে কাজ করতে পারে। - Runtime Efficiency:
Runtime-এ টাইপ সংক্রান্ত অতিরিক্ত মেটাডেটা সংরক্ষণ না করার ফলে JVM-এ কার্যকারিতা বজায় থাকে।
Type Erasure এর সীমাবদ্ধতা
Runtime এ Generics টাইপ ইনফরমেশন অনুপস্থিত:
Compile-time টাইপ চেকিং সম্ভব হলেও runtime এ Generics টাইপ ইনফরমেশন মুছে যায়। ফলে নিচের সমস্যাগুলো দেখা দিতে পারে:List<String> stringList = new ArrayList<>(); List<Integer> intList = new ArrayList<>(); System.out.println(stringList.getClass() == intList.getClass()); // trueউপরের উদাহরণে, Generics টাইপ ইনফরমেশন runtime-এ অনুপস্থিত হওয়ায় উভয় লিস্ট একই
Classহিসেবে বিবেচিত হয়।- Type Casting প্রয়োজন:
Runtime এ টাইপ ইনফরমেশন মুছে ফেলার কারণে Object থেকে নির্দিষ্ট টাইপে কাস্টিং করতে হয়। Array of Generics:
Generics এর কারণে array creation করতে সমস্যা হয়, কারণ runtime এ টাইপ ইনফরমেশন সংরক্ষিত থাকে না।List<String>[] array = new ArrayList<String>[10]; // Compile-time ErrorOverloaded Method Resolution:
Generics ব্যবহার করলে Overloaded মেথডের সমস্যা হতে পারে:public void method(List<String> list) { } public void method(List<Integer> list) { }উপরের কোড runtime এ একই মেথডে রূপান্তরিত হয় এবং কম্পাইল-টাইম এ এরর দেয়।
Type Erasure এ Annotation ব্যবহার
Annotations যেমন @SuppressWarnings("unchecked") ব্যবহার করা হয় Generics সম্পর্কিত warnings থেকে মুক্তি পেতে।
@SuppressWarnings("unchecked")
public void method() {
List<String> list = (List<String>) new ArrayList(); // Unchecked cast
}
- Type Erasure Generics এর মাধ্যমে compile-time টাইপ সেফটি নিশ্চিত করে, তবে runtime এ Generics টাইপ ইনফরমেশন মুছে ফেলে।
- এটি backward compatibility বজায় রাখার জন্য অপরিহার্য, তবে runtime টাইপ ইনফরমেশন না থাকার কারণে কিছু সীমাবদ্ধতা তৈরি হয়।
- এর সুবিধা এবং সীমাবদ্ধতাগুলি বোঝার মাধ্যমে Generics আরও কার্যকরভাবে ব্যবহার করা যায়।
জাভা জেনেরিক্স মূলত টাইপ সেফটি নিশ্চিত করার জন্য ডিজাইন করা হয়েছে এবং এর প্রধান প্রভাব compile-time এ দেখা যায়। তবে runtime এ Generics-এর আচরণ কিছুটা ভিন্ন, কারণ জাভা Generics টাইপ ইরেজার (type erasure) নামে একটি প্রক্রিয়া ব্যবহার করে।
Compile-Time এ Generics এর ভূমিকা
টাইপ সেফটি নিশ্চিত করা:
- Generics কম্পাইল টাইমে টাইপ চেকিং সম্পন্ন করে। ফলে ডেটা টাইপ সম্পর্কিত ত্রুটি (type mismatch errors) কম্পাইল টাইমেই ধরা যায়।
- এটি কোডকে আরও নির্ভুল এবং নিরাপদ করে তোলে।
উদাহরণ:
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add(10); // Compile-time error } }ত্রুটি বার্তা:
incompatible types: int cannot be converted to Stringটাইপ কাস্টিং এর প্রয়োজনীয়তা দূর করা:
- Generics ব্যবহারের ফলে টাইপ কাস্টিং করার দরকার হয় না। এটি কোডকে সহজ করে এবং runtime errors কমায়।
উদাহরণ:
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Generics"); String item = list.get(0); // No casting needed System.out.println(item); } }- কোড পুনর্ব্যবহারযোগ্যতা (Code Reusability):
- Generics ক্লাস এবং মেথড বিভিন্ন টাইপের ডেটার জন্য ব্যবহার করা যায়।
Runtime এ Generics এর ভূমিকা
জাভার type erasure এর কারণে runtime এ Generics এর টাইপ ইনফরমেশন মুছে ফেলা হয়। ফলে Generics এর টাইপ সম্পর্কিত বেশিরভাগ তথ্য compile-time এ সীমাবদ্ধ থাকে।
Runtime এর ভূমিকা:
Type Erasure:
- Generics এর টাইপ ইনফরমেশন runtime এ ইরেজ হয়ে যায়।
- এর ফলে JVM শুধুমাত্র raw টাইপের উপর কাজ করে।
উদাহরণ:
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<String> stringList = new ArrayList<>(); List<Integer> intList = new ArrayList<>(); System.out.println(stringList.getClass() == intList.getClass()); // true } }আউটপুট:
trueব্যাখ্যা:
Compile-time এList<String>এবংList<Integer>আলাদা মনে হলেও, runtime এListএর টাইপ ইরেজ হয়ে যায়। তাই একই ক্লাস টাইপ হিসেবে দেখা যায়।Type Safety Runtime এ প্রয়োগ হয় না:
- Generics runtime এ টাইপ চেক করতে পারে না। এটি compile-time এর কাজ।
- runtime এ টাইপ চেকিং এর জন্য
instanceofকাজ করে না।
উদাহরণ:
import java.util.ArrayList; public class Main { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); if (list instanceof ArrayList<String>) { // Compile-time error System.out.println("This will not compile"); } } }Backward Compatibility:
- Generics এর টাইপ ইরেজারের কারণে জাভার পুরনো (non-generic) কোডের সাথে Compatibility বজায় থাকে।
- Generics ব্যবহার করলে পুরনো
rawটাইপ ডেটার সাথে কাজ করানো সম্ভব।
উদাহরণ:
import java.util.ArrayList; public class Main { public static void main(String[] args) { ArrayList list = new ArrayList(); // Raw type list.add("Java"); list.add(10); for (Object obj : list) { System.out.println(obj); } } }আউটপুট:
Java 10
Compile-Time এবং Runtime এর তুলনা
| বৈশিষ্ট্য | Compile-Time | Runtime |
|---|---|---|
| টাইপ চেকিং | Generics টাইপ চেকিং সম্পন্ন করে। | টাইপ ইনফরমেশন মুছে ফেলা হয়। |
| টাইপ ইনফরমেশন | Generics টাইপের তথ্য দৃশ্যমান থাকে। | টাইপ ইরেজার এর কারণে অদৃশ্য। |
| টাইপ সেফটি | টাইপ সেফটি নিশ্চিত করে। | টাইপ সেফটি runtime এ প্রযোজ্য নয়। |
| Backward Compatibility | Compile-Time এ নিশ্চিত। | Runtime এ পুরনো কোড সাপোর্ট করে। |
- Compile-Time: জেনেরিক্স টাইপ চেকিং, টাইপ সেফটি এবং টাইপ কাস্টিং এড়িয়ে কোড সহজ করে।
- Runtime: টাইপ ইরেজারের কারণে Generics-এর কার্যক্ষমতা সীমিত, তবে এটি জাভার backward compatibility বজায় রাখতে সাহায্য করে।
Generics মূলত compile-time টাইপ নিরাপত্তা নিশ্চিত করতে এবং runtime এ কার্যক্ষমতার সাথে পুরনো কোডের সামঞ্জস্য বজায় রাখতে গুরুত্বপূর্ণ ভূমিকা পালন করে।
Type Erasure জাভা জেনেরিক্সের একটি মৌলিক বৈশিষ্ট্য, যা জাভার Backward Compatibility নিশ্চিত করার জন্য ব্যবহার করা হয়। এটি জেনেরিক টাইপের তথ্যকে কম্পাইল টাইমে মুছে দেয় এবং টাইপ সম্পর্কিত সমস্ত তথ্যকে রানটাইমে উপলব্ধ করে না।
তবে, এর ফলে জেনেরিক্সে কিছু সীমাবদ্ধতা সৃষ্টি হয়। নিচে Type Erasure এর কারণে জেনেরিক্সের সীমাবদ্ধতাগুলো আলোচনা করা হলো।
Type Erasure কীভাবে কাজ করে?
- Compile-Time Type Checking:
- কম্পাইলার টাইপ সম্পর্কিত চেকিং কম্পাইল টাইমে করে।
- Runtime Erasure:
- কম্পাইল টাইমের পরে জেনেরিক টাইপ তথ্য মুছে ফেলা হয়।
- এটি মূলত টাইপকে
Objectবা বাউন্ডেড টাইপে রূপান্তর করে।
উদাহরণ:
public class GenericClass<T> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
কম্পাইল করার পরে, এটি নিম্নোক্ত রূপে রূপান্তরিত হয়:
public class GenericClass {
private Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
Generics এর সীমাবদ্ধতাগুলো
১. Primitive Types সরাসরি ব্যবহার করা যায় না
জেনেরিক্স কেবলমাত্র রেফারেন্স টাইপ গ্রহণ করে, কারণ প্রিমিটিভ টাইপ (int, double ইত্যাদি) Type Erasure এর সময় Object এ রূপান্তরিত করা যায় না।
সমাধান:
Wrapper Classes (যেমন, Integer, Double) ব্যবহার করতে হয়।
// ভুল: GenericClass<int> obj = new GenericClass<>();
GenericClass<Integer> obj = new GenericClass<>();
২. Runtime Type Information হারানো
Type Erasure এর ফলে রানটাইমে টাইপ সম্পর্কিত কোনো তথ্য উপলব্ধ থাকে না। ফলে টাইপ সম্পর্কিত কাজ করা জটিল হয়।
উদাহরণ:
public static void printList(List<String> list) {
System.out.println(list);
}
public static void main(String[] args) {
List<Integer> intList = List.of(1, 2, 3);
// Runtime এ Type Erasure এর কারণে নিচের কোডটি কম্পাইল হবে:
// printList(intList); // Compile-Time Error হয় না, কিন্তু টাইপের উপর ভিত্তি করে রানটাইম সমস্যা দেখা দিতে পারে।
}
৩. Generic Arrays তৈরি করা যায় না
জেনেরিক্সের সাথে টাইপ তথ্য মুছে যায় বলে রানটাইমে সঠিক টাইপ নিশ্চিত করা সম্ভব নয়।
উদাহরণ:
// ভুল: Generic array তৈরি করা যায় না
List<String>[] array = new List<String>[10]; // Compile-Time Error
সমাধান:
// Array এর পরিবর্তে Collection ব্যবহার করুন
List<List<String>> listOfLists = new ArrayList<>();
৪. Instanceof অপারেটর ব্যবহার সীমিত
instanceof অপারেটর জেনেরিক টাইপের সাথে কাজ করে না, কারণ Type Erasure এর ফলে টাইপের তথ্য উপলব্ধ থাকে না।
উদাহরণ:
// ভুল: Generics এর সাথে instanceof ব্যবহার
if (obj instanceof List<String>) { // Compile-Time Error
System.out.println("This is a List of Strings");
}
সমাধান:
// Unbounded Wildcard ব্যবহার করুন
if (obj instanceof List<?>) {
System.out.println("This is a List");
}
৫. Static Context এ Generics ব্যবহার সীমিত
Static মেম্বারগুলি ক্লাস স্তরে থাকে এবং জেনেরিক টাইপের সাথে কাজ করতে পারে না, কারণ জেনেরিক টাইপের তথ্য Type Erasure এর সময় মুছে ফেলা হয়।
উদাহরণ:
public class GenericClass<T> {
// Static মেম্বারে জেনেরিক টাইপ ব্যবহার করা যায় না
private static T data; // Compile-Time Error
}
সমাধান:
Static মেম্বারে জেনেরিক্স ব্যবহার না করে কনক্রিট টাইপ ব্যবহার করুন।
Type Erasure জেনেরিক্সের সীমাবদ্ধতা সৃষ্টি করলেও এটি জাভার Backward Compatibility নিশ্চিত করে। এর ফলে জেনেরিক্সের কিছু সীমাবদ্ধতা রয়েছে:
- Primitive Types সরাসরি ব্যবহার করা যায় না।
- Runtime এ টাইপ সম্পর্কিত তথ্য উপলব্ধ থাকে না।
- Generic Arrays তৈরি করা যায় না।
instanceofঅপারেটর সরাসরি ব্যবহার করা যায় না।- Static মেম্বারে Generics ব্যবহার সীমিত।
যদিও এই সীমাবদ্ধতাগুলি রয়েছে, জেনেরিক্সের সঠিক ব্যবহার করলে কোড টাইপ-নিরাপদ, পুনঃব্যবহারযোগ্য এবং আরও পরিষ্কার হয়।
জাভা জেনেরিক্স মূলত টাইপ-সেইফটি নিশ্চিত করতে এবং ClassCastException এড়ানোর জন্য ডিজাইন করা হয়েছে। এটি Runtime Type Checking-এও সাহায্য করে, যেখানে কম্পাইল-টাইমে অনেক সমস্যার সমাধান হয়। তবে, কিছু নির্দিষ্ট ক্ষেত্রে জেনেরিক্স ব্যবহার করার সময় এই চ্যালেঞ্জগুলো গুরুত্বপূর্ণ হয়ে ওঠে।
ClassCastException এবং জেনেরিক্স
ClassCastException ঘটে যখন কোনো অবজেক্টকে ভুল টাইপে কাস্ট করার চেষ্টা করা হয়। জেনেরিক্স টাইপ সেফটি নিশ্চিত করে এই সমস্যা সমাধান করে।
জেনেরিক্স ছাড়া উদাহরণ:
import java.util.ArrayList;
import java.util.List;
public class WithoutGenerics {
public static void main(String[] args) {
List list = new ArrayList();
list.add("Hello");
list.add(10); // Adding Integer to a raw type list
// Type casting required
for (Object obj : list) {
String str = (String) obj; // Throws ClassCastException for Integer
System.out.println(str);
}
}
}
আউটপুট:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
জেনেরিক্স দিয়ে সমাধান:
import java.util.ArrayList;
import java.util.List;
public class WithGenerics {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
// list.add(10); // Compile-time error: incompatible types
for (String str : list) {
System.out.println(str);
}
}
}
আউটপুট:
Hello
Runtime Type Checking
জেনেরিক্স টাইপ চেকিং Compile-Time-এ ঘটে। তবে জাভার Type Erasure-এর কারণে Runtime-এ জেনেরিক টাইপ সম্পর্কিত তথ্য মুছে যায়।
Type Erasure এবং Runtime Type Checking উদাহরণ
import java.util.ArrayList;
public class TypeErasureExample {
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList<>();
stringList.add("Hello");
// At runtime, the type information is erased
if (stringList instanceof ArrayList) {
System.out.println("This is an ArrayList");
}
// Following will cause a compile-time error:
// if (stringList instanceof ArrayList<String>) { }
}
}
আউটপুট:
This is an ArrayList
ClassCastException এড়াতে জেনেরিক্সের ভূমিকা
- Raw Type এড়ানো: জেনেরিক্স ব্যবহার করে টাইপ সেফ লিস্ট তৈরি করুন।
- Compile-Time Checking: টাইপ মিসম্যাচ আগে থেকেই শনাক্ত হয়।
- কাস্টিং এড়ানো: টাইপ কাস্টিং ছাড়া সরাসরি উপযুক্ত টাইপ ব্যবহার করা যায়।
Type Checking জেনেরিক মেথডে
public class GenericTypeCheck {
public static <T> void addIfInstance(List<T> list, Object obj) {
if (obj.getClass().isInstance(list.get(0))) {
list.add((T) obj);
} else {
System.out.println("Type mismatch");
}
}
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
stringList.add("Java");
addIfInstance(stringList, "Generics"); // Works
addIfInstance(stringList, 10); // Prints "Type mismatch"
}
}
আউটপুট:
Type mismatch
কোডে ClassCastException এর প্রকৃত ব্যবস্থাপনা
Custom Runtime Checks:
public static <T> void safeAdd(List<T> list, Object obj) { if (obj instanceof String) { list.add((T) obj); // Only if type matches } else { System.out.println("Cannot add incompatible type"); } }Generic Wrapper Class:
public class SafeWrapper<T> { private T data; public SafeWrapper(T data) { this.data = data; } public T getData() { return data; } }
- ClassCastException এড়াতে জেনেরিক্স অপরিহার্য।
- Compile-Time Type Checking জাভার টাইপ সেফ কোড নিশ্চিত করে।
- Runtime Type Checking বিশেষ ক্ষেত্রে দরকার হতে পারে, তবে এটি Type Erasure-এর কারণে সীমাবদ্ধ।
- সঠিক ব্যবহারে জেনেরিক্স বড় আকারের প্রজেক্টে বাগ-মুক্ত কোড তৈরি করতে সাহায্য করে।
Read more